8

I'm using the following code (written by another user) to throttle ajax requests in a livesearch function:

JSFiddle if you prefer a demo: http://jsfiddle.net/4xLVp/

It seems buggy, though. Clearing values with Ctrl+shift+back-arrow, and typing again causes a flurry of requests. Blank values also cause a request. It dones't seem right, especially compared to jQuery UI autocomplete, where request delays seem more measured.

    $('##tag-search').keyup(function() {
        var elem = $(this);
        if (elem.val().length >= 2) {
            elem.data('search',search).clearQueue().stop().delay(1000).queue(function() {
                $.ajax({ // ajax stuff
                    'success': function(data){ /*show result*/ }
                });
                if (elem.data('search') !=  string) return;
            });                                             
        } else if (string.length <= 1) { /*show original content*/ }
    });

Is there a better way to handle this?

Community
  • 1
  • 1
Mohamad
  • 34,731
  • 32
  • 140
  • 219

1 Answers1

8

I would just use setTimeout:

(function() {
    var timeout;
    $('#tag-search').keyup( function() {
        var elem = $(this);
        if (elem.val().length >= 2) {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
               $.ajax({ // ajax stuff
                    'success': function(data){ /*show result*/ }
                });     
            }, 80); // <-- choose some sensible value here                                      
        } else if (string.length <= 1) { /*show original content*/ }
    });
}());

There is also a debounce/throttle plugin.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks. That's done the trick, I'm surprised it's that simple. Can you please explain what the clearTimeout() does and why it's needed? – Mohamad Aug 07 '11 at 19:27
  • setTimeout - sets a code which would be executed after some time, clearTimeout - removes that pending execution, it's needed to clear earlier peding ajax request before starting new one – Jacek Kaniuk Aug 07 '11 at 19:54
  • BTW - I do not recommend removal of `if (elem.data('search') != string) return;` part, it prevents earlier ajax calls (lasting longer) from updating already changed results – Jacek Kaniuk Aug 07 '11 at 19:57
  • @Jacek_FH: How? As far as I can see, this statement is doing nothing. It is not inside the Ajax call. The function will return after that statement anyway. *Edit:* Ah, in the original code (the one that the OP links to) this statement is inside the Ajax callback. – Felix Kling Aug 07 '11 at 23:08