• Jump To … +
    search_facets.js search_query.js templates.js backbone_extensions.js hotkeys.js inflector.js jquery_extensions.js search_parser.js search_box.js search_facet.js search_input.js visualsearch.js
  • search_parser.js

  • ¶
    (function() {
    
    var $ = jQuery; // Handle namespaced jQuery
  • ¶

    Used to extract keywords and facets from the free text search.

    var QUOTES_RE   = "('[^']+'|\"[^\"]+\")";
    var FREETEXT_RE = "('[^']+'|\"[^\"]+\"|[^'\"\\s]\\S*)";
    var CATEGORY_RE = FREETEXT_RE +                     ':\\s*';
    VS.app.SearchParser = {
  • ¶

    Matches category: "free text", with and without quotes.

      ALL_FIELDS : new RegExp(CATEGORY_RE + FREETEXT_RE, 'g'),
  • ¶

    Matches a single category without the text. Used to correctly extract facets.

      CATEGORY   : new RegExp(CATEGORY_RE),
  • ¶

    Called to parse a query into a collection of SearchFacet models.

      parse : function(instance, query) {
        var searchFacets = this._extractAllFacets(instance, query);
        instance.searchQuery.reset(searchFacets);
        return searchFacets;
      },
  • ¶

    Walks the query and extracts facets, categories, and free text.

      _extractAllFacets : function(instance, query) {
        var facets = [];
        var originalQuery = query;
        while (query) {
          var category, value;
          originalQuery = query;
          var field = this._extractNextField(query);
          if (!field) {
            category = instance.options.remainder;
            value    = this._extractSearchText(query);
            query    = VS.utils.inflector.trim(query.replace(value, ''));
          } else if (field.indexOf(':') != -1) {
            category = field.match(this.CATEGORY)[1].replace(/(^['"]|['"]$)/g, '');
            value    = field.replace(this.CATEGORY, '').replace(/(^['"]|['"]$)/g, '');
            query    = VS.utils.inflector.trim(query.replace(field, ''));
          } else if (field.indexOf(':') == -1) {
            category = instance.options.remainder;
            value    = field;
            query    = VS.utils.inflector.trim(query.replace(value, ''));
          }
    
          if (category && value) {
              var searchFacet = new VS.model.SearchFacet({
                category : category,
                value    : VS.utils.inflector.trim(value),
                app      : instance
              });
              facets.push(searchFacet);
          }
          if (originalQuery == query) break;
        }
    
        return facets;
      },
  • ¶

    Extracts the first field found, capturing any free text that comes before the category.

      _extractNextField : function(query) {
        var textRe = new RegExp('^\\s*(\\S+)\\s+(?=' + QUOTES_RE + FREETEXT_RE + ')');
        var textMatch = query.match(textRe);
        if (textMatch && textMatch.length >= 1) {
          return textMatch[1];
        } else {
          return this._extractFirstField(query);
        }
      },
  • ¶

    If there is no free text before the facet, extract the category and value.

      _extractFirstField : function(query) {
        var fields = query.match(this.ALL_FIELDS);
        return fields && fields.length && fields[0];
      },
  • ¶

    If the found match is not a category and facet, extract the trimmed free text.

      _extractSearchText : function(query) {
        query = query || '';
        var text = VS.utils.inflector.trim(query.replace(this.ALL_FIELDS, ''));
        return text;
      }
    
    };
    
    })();