Sinan
Sinan

Reputation: 5980

delaying actions between keypress in jQuery

How can I delay actions between keypress in jQuery. For example;

I have something like this

 if($(this).val().length > 1){
   $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
    if(data.length > 0) {
      $('#suggestions').show();
      $('#autoSuggestionsList').html(data);
    }else{
      $('#suggestions').hide();
    }
 });
}

I want to prevent posting data if the user continously typing. So how can I give .5 seconds delay?

Upvotes: 31

Views: 25112

Answers (5)

Huy Le
Huy Le

Reputation: 667

Nick's answer is perfect but if handling first event immediately is critical then I think we can do:

$(selector).keyup(function(e){ //or another event

    if($(this).val().length > 1){
        if !($.data(this, 'bouncing-locked')) {

            $.data(this, 'bouncing-locked', true)

            $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
                if(data.length > 0) {
                    $('#suggestions').show();
                    $('#autoSuggestionsList').html(data);
                }else{
                    $('#suggestions').hide();
                }
           });

            self = this
            setTimeout(function() {
                $.data(self, 'bouncing-locked', false);

                //in case the last event matters, be sure not to miss it
                $(this).trigger("keyup"); // call again the source event
            }, 500)
        }
    }
});

Upvotes: 2

PetersenDidIt
PetersenDidIt

Reputation: 25620

There is a nice plugin to handle this. jQuery Throttle / Debounce

Upvotes: 3

thaBadDawg
thaBadDawg

Reputation: 5220

I'd wrap it in a function like so:

  var needsDelay = false;

  function getSuggestions(var search)
  {
    if(!needsDelay)
    {
        needsDelay = true;
        setTimeout("needsDelay = false", 500);

        if($(this).val().length > 1){
            $.post("stuff.php", {nStr: "" + search + ""}, function(data){
                if(data.length > 0) {
                    $('#suggestions').show();
                    $('#autoSuggestionsList').html(data);
                }else{
                    $('#suggestions').hide();
                }
            });
        }
    }


  }

That way no matter how many times you ping this, you will never search more than every 500 milliseconds.

Upvotes: 1

Jerod Venema
Jerod Venema

Reputation: 44632

All you need to do is wrap your function in a timeout that gets reset when the user presses a key:

var ref;
var myfunc = function(){
   ref = null;
   //your code goes here
};
var wrapper = function(){
    window.clearTimeout(ref);
    ref = window.setTimeout(myfunc, 500);
}

Then simply invoke "wrapper" in your key event.

Upvotes: 11

Nick Craver
Nick Craver

Reputation: 630429

You can use jQuery's data abilities to do this, something like this:

$('#mySearch').keyup(function() {
  clearTimeout($.data(this, 'timer'));
  var wait = setTimeout(search, 500);
  $(this).data('timer', wait);
});

function search() {
  $.post("stuff.php", {nStr: "" + $('#mySearch').val() + ""}, function(data){
    if(data.length > 0) {
      $('#suggestions').show();
      $('#autoSuggestionsList').html(data);
    }else{
      $('#suggestions').hide();
    }
  });
}

The main advantage here is no global variables all over the place, and you could wrap this in an anonymous function in the setTimeout if you wanted, just trying to make the example as clean as possible.

Upvotes: 66

Related Questions