1

I'm using jQuery Autocomplete to show results from a list of approximately 2000 records. Because this list is in my opinion very long I need a good filter to search through all these records.

I already modified the source so that I was able to search not only in the label field, but also in the value field. What I now want is that I can do a search for "S4 galaxy" where it wil find the "Samsung Galaxy S4". The standard jquery autocomplete can only search from left to right, so "galaxy s4" will be found, but not "s4 galaxy". I also want to look at "gal s4" and find the "Samsung Galaxy S4".

As an extra, it would be nice if the match is made bold > "Samsung Galaxy S4"

The complete code I now use stands below:

var completeResults = [{
    value: "S4 iv",
    label: "Samsung Galaxy S4",
    image: "samsung_galaxy_s_iv_1.jpg"
}, {
    value: "stackoverflow",
    label: "Nokia lumia 920",
    image: "nokia_lumia_920_1.jpg"
}];

completeResults is now a short list! Normaly about 2000 records.

function custom_source(request, response) {
    var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
    response($.grep(completeResults, function (value) {
        return matcher.test(value.value) || matcher.test(value.label);
    }));
}

$("#s").autocomplete({
    source: custom_source,
    minLength: 0
}).data("ui-autocomplete")._renderItem = function (ul, item) {
    var inner_html = "<a><img src='../img/type/120x200/" + item.image + "' width='21' height='35'/><span class='title'>" + item.label + "</span></a>";

    return $("<li></li>")
        .data("item.autocomplete", item)
        .append(inner_html)
        .appendTo(ul);
};
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
Timo002
  • 3,138
  • 4
  • 40
  • 65
  • With that many records you might be better of doing your searching on the server – Andrew Whitaker May 02 '13 at 12:47
  • Well, I wanted to do this in the browser so I would have less database queries. How could I do this server side? With PHP? I do not want to query the database continously because that will give me a lot of database usage if a few thousand people use this every day! – Timo002 May 02 '13 at 12:57
  • That's true, definitely a trade off. Your web server is made to handle thousands of requests though. One more question--If I type "Nokia Samsung" should I get both results back? Or does each term have to be found in the suggestion items? – Andrew Whitaker May 02 '13 at 13:06
  • "Nokia Samsung" would give no result. Only all matches in one item! – Timo002 May 02 '13 at 13:15

1 Answers1

2

Okay here's something that should work (minus the bolding of text, which I'll get to). Basically the strategy is to:

  1. Create a regular expression out of each term the user types. We can do that by splitting the input on ' '.
  2. For every choice in the list of possible choices, see if that choice matches every single regex we extracted in step 1.
  3. Only return the values that meet the criteria in step 2.
function custom_source(request, response) { 
    // Create an array of regular expressions from the user's input:
    var terms = $.map(request.term.split(' '), function (term) {
        // Ignore just whitespace:
        if ($.trim(term)) {
            return new RegExp($.ui.autocomplete.escapeRegex(term), 'i');
        }
    });

    response($.grep(completeResults, function (value) {
        var found = true
            , i
            , regex;

        // For every result, iterate over every term we extracted earlier and make sure it matches:
        for (i = 0; i < terms.length && found; i++) {
            regex = terms[i];
            found = found && (regex.test(value.value) || regex.test(value.label));
        }

        return found;
    }));
}

Example: http://jsfiddle.net/Aa5nK/73/

The other part of your question is answered in the following question:

jQueryUI: how can I custom-format the Autocomplete plug-in results?

Community
  • 1
  • 1
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • The only thing is I would say the format solution would have been better had it used a CSS class and not embedded style. +1 for the link – Mark Schultheiss May 02 '13 at 13:31
  • Great, this works fine! I'm going to test it and if OK, this will be the answer. However, in IE10 it's very slow.. this is a problem because it's all done by the browser? Will in that case server side be better? And if so, can I do that in a already prepared file so I don't need any SQL queries. – Timo002 May 02 '13 at 13:43
  • @Timo002: I can try using one regex instead of testing against a regex for each term. And yes it's slow because the browser is doing the filter. One second and I'll update the answer – Andrew Whitaker May 02 '13 at 13:45
  • @Timo002: Hmm, I take that back, maybe it's not as easy as I thought it would be. I'll keep at it though. – Andrew Whitaker May 02 '13 at 13:57
  • @AndrewWhitaker: Your code is working perfectly. However as you already mentioned.. server side might be faster. In Chrome the response is relatively fast. But in IE10 it is terribly slow. So now I might be looking for a server side solution.. I think AJAX / PHP, but than I want it searching through a local file, not in a database. – Timo002 May 02 '13 at 14:04