views:

370

answers:

3

I have a page where search resuts are shown both in a grid and on a map (using KML generated on the fly, overlaid on an embedded Google map). I've wired this up to work as the user types; here's the skeleton of my code, which works:

$(function() {
    // Wire up search textbox
    $('input.Search').bind("keyup", update);
});

update = function(e) {
    // Get text from search box
    // Pass to web method and bind to concessions grid
    $.ajax({  
        ...
        success: function(msg) {
            displayResults(msg, filterParams);
        },
    });

}

displayResults = function(msg, filterParams) {
        // Databind results grid using jTemplates
        // Show results on map: Pass parameters to KML generator and overlay on map
}

Depending on the search, there may be hundreds of results; and so the work that happens in displayResults is processor-intensive both on the server (querying the database, building and simplifying the KML on the fly) and on the client (databinding the results grid, overlaying big KML files on the map).

I like the immediacy of getting progressively narrower results as I type, but I'd like to minimize the number of times this refreshes. What's the simplest way to introduce an N-second delay after the user stops typing, before running the update function?

A: 

As a first approach, what about something like :

$('input.Search').bind("keyup", function() { setTimeout(update, 5) } );

(not sure about the exact setTimeout syntax).

You can also keep a variable to track whether the timeout has already been scheduled or not.

Guido
That will effectively incur the same amount of unnecessary load, after waiting for 5 milliseconds.
Ates Goral
A: 

You can use Window.SetTimeOut(YourRefreshMethod) , when the YourRefereshMethod gets called, it will check number of characters being typed so far , and compare it to the some counter, the counter will starts with 0 value, so the initial call will do nothing other than updating the counter with the current characters typed count, the second time your method get called , it will check the number of characters typed, if it matches the previous number recorded by the counter , then it means the user didn't type anything new and you can fire your Refresh method, otherwise you will update the counter value

Mohamed Faramawi
+3  A: 

Instead of calling update() directly, call a wrapper that checks to see if there are any pending delayed updates:

$('input.Search').bind("keyup", delayedUpdate);

function delayedUpdate() {
    if (updatePending) {
        clearTimeout(updatePending);
    }

    updatePending = setTimeout(update, 250);
}

function update() {
    updatePending = false;

    //$.ajax(...
}

You should also probably add:

$('input.Search').bind("blur", update);

This will do an immediate update when the user leaves the field. But make sure you also add handling for the case where the user leaves the field while there's a pending delayed update (cancel the delayed update first).

Ates Goral
This works perfectly - thanks.
Herb Caudill