Simple jQuery search on input element Just wanted a way of attaching a jQuery search plugin to an input element (or collection) and be able to pass specific options at invoke time:

This is the plugin code

(function($){

$.fn.extend({

  enableSearch:function(opts,callback){
    return this
    .bind('focus',function(){
      $(this.form.elements).val(''); // clears all search inputs
      $(this).trigger('keyup'); // triggers the search on an empty input element
    }) // END focus bind
    .bind('keyup',function(){
       var searchData = $.extend({},'source':this.form.id,'column':$(this).attr('id'),'value':$(this).val()},opts);
       $.ajax({
         url:opts.URL,
         type:'post',
         data:searchData,
         dataType:'json'
       })
       .promise().then(function(returndata){
         callback(returndata);
       }); // END ajax call
       return false;
    }); // END bind keyup
  } //END fn enableSearch

})

})(jQuery);


This is the call on the collection:

$('input') // collection on which to enable searching
  .enableSearch({
   URL:'&lt;server side script url&gt;',
   extra_param:extra_param_value, // extra param which gets passed in the data to the server side fn
  },function(data){
    //actions performed on the returned data, e.g. update a list
  });


I couldn't get my idea to work until I came across the jQuery promise implmentation. Opens many doors.

Works for me - any thoughts?
I find $.ajax().promise().then(fn) to be a little more confusing when looking at the code than it would have been if you instead used $.ajax().complete(fn) (or success if that is what you meant).
I would throttle the ajax post so that it doesn't happen on every keyup
if you are using the latest syntax already for $.ajax, I think it makes sense to use the .on method instead of .bind
some of the $() calls can be cached at various levels


So far the resulting code looks something like this (completely untested):

(function($, window){
    $.fn.extend({
        enableSearch:function(opts,callback){
            var timeout;
            var $t = this;
            return $t               
                .on({
                    focus: function(){
                        $(this.form.elements).val(''); // clears all search inputs
                        $t.trigger('keyup'); // triggers the search on an empty input element
                    }, // END focus bind
                    keyup: function(){
                        var t = this;
                        if (timeout) { window.clearTimeout(timeout); }
                        timeout = window.setTimeout(function() {
                            var searchData = $.extend({}, {
                                source:t.form.id,
                                column:$t.attr('id'),
                                value:$t.val()
                            }, opts);

                            $.ajax({
                                url:opts.URL,
                                type:'post',
                                data:searchData,
                                dataType:'json'
                            }).complete(function(returndata){
                                callback(returndata);
                            }); // END ajax call
                        }, $.fn.enableSearch.throttle); //END setTimeout
                    } //END keyup
                }); //END on
        } //END fn enableSearch
    });
    $.fn.enableSearch.throttle = 150; //$.ajax will not happen until 150 ms delay happens between keystrokes
}(jQuery, window));


This code is still very specific to your particular case and isn't very reusable elsewhere. The only reasons I would even be making it into a plugin are testability and reuse. I suppose you may be able to reuse this on your application so that isn't much of a deal, but I feel like it requires too much knowledge of your specific implementation to be testable.