Search code examples
javascriptjqueryajaxtimeautosuggest

Efficient AutoSuggest with jQuery?


I'm working to build a jQuery AutoSuggest plugin, inspired by Apple's spotlight.

Here is the general code:

$(document).ready(function() { 
$('#q').bind('keyup', function() {

    if( $(this).val().length == 0) {
        // Hide the q-suggestions box
        $('#q-suggestions').fadeOut();
    } else {
        // Show the AJAX Spinner
        $("#q").css("background-image","url(/images/ajax-loader.gif)");

        $.ajax({
            url: '/search/spotlight/',
            data: {"q": $(this).val()},
            success: function(data) {
                $('#q-suggestions').fadeIn(); // Show the q-suggestions box
                $('#q-suggestions').html(data); // Fill the q-suggestions box

                // Hide the AJAX Spinner
                $("#q").css("background-image","url(/images/icon-search.gif)");

            }
        });
    }
});

The issue I want to solve well & elegantly, is not killing the sever. Right now the code above hits the server every time you type a key and does not wait for you to essentially finish typing. What's the best way to solve this? A. Kill previous AJAX request? B. Some type of AJAX caching? C. Adding some type of delay to only submit .AJAX() when the person has stopped typing for 300ms or so?


Solution

  • Try using Ben Alman's Throttle & Debounce plugin

    Lets you "delay" things till the user is done.

    For an example on how to use it check out his example of debouncing with a pretend autocomplete

    Your code would basically become

    var qinput = $('#q').bind('keyup', $.debounce( 250, function() {
    
        if( $(this).val().length == 0) {
            // Hide the q-suggestions box
            $('#q-suggestions').fadeOut();
        } else {
            // Show the AJAX Spinner
            qinput.addClass('loading');
    
            $.ajax({
                url: '/search/spotlight/',
                data: {"q": $(this).val()},
                success: function(data) {
                    $('#q-suggestions')
                        .fadeIn() // Show the q-suggestions box
                        .html(data); // Fill the q-suggestions box
    
                    // Hide the AJAX Spinner
                   qinput.removeClass('loading').addClass('search');
                }
            });
        }
    }));
    

    CSS

    .loading{
        background: url('/images/ajax-loader.gif');
    }
    .search{
        background: url('/images/icon-search.gif');
    }
    

    You will note that I removed your background-image css and replaced them with addClass/removeClass. Much easier to manage css stuff in css files.