jQuery Bind Delayed Get: code highly appropriate for fetching updated results as the user types.

posted 2012-Mar-23

In order to give the fastest, best feedback to the user, you want to populate some results while the user is typing. Maybe it’s a simple autocomplete form; maybe you’re performing live queries on the database while they fill out a regex.

If you send an XHR request on every keyup event you’re going to crush your network and server. You probably want to wait 50ms or 100ms and only send the request if they haven’t typed another key yet. You also want to make sure that if you do have multiple requests in the air at the same time that you always show the user the request based on the last information they sent.

To these ends I give you jQuery.bindDelayed:

(function($){
  // Instructions: http://phrogz.net/jquery-bind-delayed-get
  // Copyright:    Gavin Kistner, !@phrogz.net
  // License:      http://phrogz.net/js/_ReuseLicense.txt
  $.fn.bindDelayed = function(event,delay,url,dataCallback,callback,dataType,action){
    var xhr, timer, ct=0;
    return this.on(event,function(){
      clearTimeout(timer);
      if (xhr) xhr.abort();
      timer = setTimeout(function(){
        var id = ++ct;
        xhr = $.ajax({
          type:action||'get',
          url:url,
          data:dataCallback && dataCallback(),
          dataType:dataType||'json',
          success:function(data){
            xhr = null;
            if (id==ct) callback.call(this,data);
          }
        });
      },delay);
    });
  };
})(jQuery);

Example

Here’s the actual code used on the admin for this site to give me a live preview while I edit any aspect of a page:

$('#title,#name,#description,#content').bindDelayed('keyup change',200,'/admin/preview',function(){
  return $('form').serialize();
},function(html){
  previewFrame.document.write(html);
  previewFrame.document.close();
},'html','post');
net.mind details contact résumé other
Phrogz.net