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?
1 Answer 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). - 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.