Search code examples
jqueryajaxjsondelay

A jQuery search box, search results does not match input


Firstly, the title was the best I could come up with.

I have written a very short little script to perform live search.

The basics of it is:

(function ($) {
    $.fn.SearchThing = function (options) {
        options = $.extend({
            MaxCount: 5,
            inputField: '#search_input',
            sugestBox: '#search_sugest'
        }, options);

        var input = $(options.inputField);
        var sugest = $(options.sugestBox);
        sugest.hide();

        input.keyup(function (e) {
            switch (e.keyCode) {
                //Other keys.
                default:
                    queryServer(this.value);
            }
        });

        function queryServer(value) {
            var url = "/search/get?query=" + value; // value;
            $.getJSON(url, function (result) {
                if (result.Results < 1) {
                    sugest.hide();
                    return;
                }

                sugest.children().each(function (idx, itm) {
                    $(itm).remove();
                });
                sugest.show();

                //Build box.
            }
        };
    };
})(jQuery);

And that almost works just fine. There is 2 things to be desired though. One that is not really that important and then another which is actually a bug, that might be solved by the other though, I don't know. But here they are:

BUG: Results does not always match whats in the "input field"

What this means is that if I type "ASD" it performs a search for "ASD", so if i say type "ASD" followed by a rapid "backspace" it should search for "AS", however now and then it seems to end up with the results for "ASD".

I know this because I currently haven't implemented the search back-end, so I return a static list where the first element is the search term.

I figure that this may be because the search for "AS" returned sooner than the search for "ASD" so the results are applied in the order -> "A", "AS", "AS", "ASD" where they should be applied in the order "A", "AS", "ASD", "AS"....

It also occurs that if I type "ASD" it will apply it in order -> "A", "ASD", "AS". (Same thing happens, the search for "ASD" returns before the search for "AS")

Note: Short search terms like "ASD" rarely trigger this bug, longer ones with more rapid typing is more likey to do so, I used the short one here to make the description of the problem easier.

Can anyone suggest a good solution to that?

DESIRED: A Small delay before a search is submitted, if keystrokes are rapid only the last "value" is processed.

This may actually solve the issue above, actually highly likely to do so I think.

I have looked shortly at "delay", but since it can't "cancel" the execution (as far as I understood it) it would require allot of implementation as I see it, but maybe someone has a brilliant idea on that part.

Otherwise does anyone has any other ideas on how to do this?


Solution

  • The reason for all of this is that request-response takes longer than the next key press, so the previous results show up.

    I think you should be able to fix both "issues" with a single trick:

    var delayTime = 500;
    var lastTimeout = null;
    var input = $(options.inputField);
    var sugest = $(options.sugestBox);
    sugest.hide();
    
    input.keyup(function (e) {
        switch (e.keyCode) {
            //Other keys.
            default:
                if (lastTimeout != null) {
                    clearTimeout(lastTimeout);
                }
                lastTimeout = setTimeout('queryServer("'+this.value+'")', delayTime);
        }
    });
    
    function queryServer(value) {
        lastTimeout = null;
        // ... all the rest as before ...
    };
    

    This will show the suggestions only 0.5 second after you stop typing (or make a pause this long).