Most of my programming experience is in PHP, and I have always been a bit wary of JavaScript.

I have a JavaScript class to manage executing, caching and displaying search results.

class Search

    # @property {string} The previous search term.
    @previousSearch = undefined
    # @property {HTMLElement} The element to display the search results.
    @resultsBox = undefined
    # @property {Object} An object to store cached search results.
    @cache = {}
    # @property {boolean} A flag showing if the close event listener has been set.
    eventSet = false

    constructor: (t, elm) ->
        term = t.value
        Search.resultsBox = document.getElementById elm
        if not eventSet
            Search.resultsBox.addEventListener "click", (event) ->
                if event.originalTarget.dataset.close
            eventSet = true
        if Search.isCached term
            displayCached term
            doSearch term

    # Executes a search
    doSearch = (term) ->
        if document.getElementById("dpt")
            dptW = document.getElementById("dpt" + elmId).offsetWidth + 4;
            dpt = document.getElementById("dpt" + elmId).value;
            dptW = ""
            dpt = ""
        if term isnt Search.previousSearch
            if term.length > 0
                window.makePOSTRequest "/inc/rpc/search.php", "q=#{term}&elm=#{Search.resultsBox.id}&dpt=#{dpt}"
        Search.previousSearch = term

    # Builds search results from a cached search
    displayCached = (term) ->
        cachedResult = Search.getCached term
        if cachedResult.results.length < 1
            return doSearch term
        addFooter cachedResult.resultCount, term, cachedResult.url, cachedResult.results.length, true
        addProduct product.name, product.url, product.image, product.price, true for product in cachedResult.results

    # Displays the search result box
    openDrop: ->
        sr = Search.resultsBox;
        sr.style.display = "block"

    # Hides and clears the search results
    closeDrop: ->
        sr = Search.resultsBox
        sr.style.display = "none"
        sr.innerHTML = ""

    # Adds a new item row to the search results
    addProduct: (name, web_link, image, price, cached) ->
        if cached isnt true
            cached = false
        sr = Search.resultsBox
        # ... outputs html
        if not cached
            Search.cacheSearchResult {'name' : name, 'url': web_link, 'image': image, 'price': price}

    # Adds a footer to the search results
    addFooter: (count, string, url, topS, cached) ->
        if cached isnt true
            cached = false
        sr = Search.resultsBox
        # ... outputs html
        if not cached
            Search.cacheSearchTerm string, {resultCount : count, url: url}

    # Returns a cached search result
    @getCached: (term) ->
        if Search.cache.hasOwnProperty term
            return Search.cache[term]
        return {}

    # Determins if a search is cached
    @isCached: (term) ->
        if Search.cache.hasOwnProperty term
            return true
        return false

    # Adds a search term to the cache
    @cacheSearchTerm: (term, data) ->
        data.results = []
        Search.cache[term] = data

    # Adds a search result item the the cache
    @cacheSearchResult: (data) ->
        Search.cache[Search.previousSearch].results.push data

    # Static methods
    @openDrop = Search::openDrop
    @closeDrop = Search::closeDrop
    @addProduct = Search::addProduct
    @addFooter = Search::addFooter

My questions are:

  • Am I doing anything wrong?
  • Should you use static methods in JavaScript?
  • Should the search and cache functionality be its own class and the HTML generation and display be its own class (like a view)?
  • Should I use a Singleton?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.