1
\$\begingroup\$

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:'<server side script url>',
   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?

\$\endgroup\$
2
\$\begingroup\$
  1. 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).
  2. I would throttle the ajax post so that it doesn't happen on every keyup
  3. if you are using the latest syntax already for $.ajax, I think it makes sense to use the .on method instead of .bind
  4. 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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.