Reputation: 1711
I'm trying to implement this answer in my own code:
$(document).ready(function() {
$('#qty').delayKeyup(function() {
var qty = $(this).val();
$(this).val(Math.round(qty / 10) * 10);
}, 1000);
});
(function ($) {
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback, ms);
});
return $(this);
};
})(jQuery);
but no change in the input value is occurring. If I remove the delayKeyup function the change works OK but obviously not with the delay. What am I missing?
Upvotes: 1
Views: 1450
Reputation: 414016
You need to make sure that the handler function is invoked with the proper this
value:
var timer = 0, elem = this;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback.bind(elem), ms);
});
Your callback is written to expect that this
will be the DOM element involved.
Also, it's good practice to make sure that your jQuery add-on methods behave like good jQuery citizens. In a case like this, you should be using .each()
in case the selector for "delayKeyup" refers to multiple elements:
(function ($) {
$.fn.delayKeyup = function(callback, ms){
return this.each(function() { // $(this) not necessary for a jQuery add-on
var timer = 0, elem = this;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback.bind(elem), ms);
});
});
};
})(jQuery);
Not all browsers support .bind()
, but luckily in this case there's a really simple alternative that works everywhere:
(function ($) {
$.fn.delayKeyup = function(callback, ms){
return this.each(function() {
var timer = 0, elem = this;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout( function() { callback.call(elem); }, ms);
});
});
};
})(jQuery);
Upvotes: 4