I want to trigger an ajax request when the user has finished typing in a text box. I don\'t want it to run the function on every time the user types a letter because that wo
Declare the following delay
function:
var delay = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})()
and then use it:
let $filter = $('#item-filter');
$filter.on('keydown', function () {
delay(function () {
console.log('this will hit, once user has not typed for 1 second');
}, 1000);
});
You can use the onblur event to detect when the textbox loses focus: https://developer.mozilla.org/en/DOM/element.onblur
That's not the same as "stops typing", if you care about the case where the user types a bunch of stuff and then sits there with the textbox still focused.
For that I would suggest tying a setTimeout to the onclick event, and assuming that after x amount of time with no keystrokes, the user has stopped typing.
Late answer but I'm adding it because it's 2019 and this is entirely achievable using pretty ES6, no third party libraries, and I find most of the highly rated answers are bulky and weighed down with too many variables.
Elegant solution taken from this excellent blog post.
function debounce(callback, wait) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(function () { callback.apply(this, args) }, wait);
};
}
window.addEventListener('keyup', debounce( () => {
// code you would like to run 1000ms after the keyup event has stopped firing
// further keyup events reset the timer, as expected
}, 1000))
Not sure if my needs are just kind of weird, but I needed something similar to this and this is what I ended up using:
$('input.update').bind('sync', function() {
clearTimeout($(this).data('timer'));
$.post($(this).attr('data-url'), {value: $(this).val()}, function(x) {
if(x.success != true) {
triggerError(x.message);
}
}, 'json');
}).keyup(function() {
clearTimeout($(this).data('timer'));
var val = $.trim($(this).val());
if(val) {
var $this = $(this);
var timer = setTimeout(function() {
$this.trigger('sync');
}, 2000);
$(this).data('timer', timer);
}
}).blur(function() {
clearTimeout($(this).data('timer'));
$(this).trigger('sync');
});
Which allows me to have elements like this in my application:
<input type="text" data-url="/controller/action/" class="update">
Which get updated when the user is "done typing" (no action for 2 seconds) or goes to another field (blurs out of the element)
I was implementing the search at my listing and needed it to be ajax based. That means that on every key change, searched results should be updated and displayed. This results in so many ajax calls sent to server, which is not a good thing.
After some working, I made an approach to ping the server when the user stops typing.
This solution worked for me:
$(document).ready(function() {
$('#yourtextfield').keyup(function() {
s = $('#yourtextfield').val();
setTimeout(function() {
if($('#yourtextfield').val() == s){ // Check the value searched is the latest one or not. This will help in making the ajax call work when client stops writing.
$.ajax({
type: "POST",
url: "yoururl",
data: 'search=' + s,
cache: false,
beforeSend: function() {
// loading image
},
success: function(data) {
// Your response will come here
}
})
}
}, 1000); // 1 sec delay to check.
}); // End of keyup function
}); // End of document.ready
You will notice that there is no need to use any timer while implementing this.
If you need wait until user is finished with typing use simple this:
$(document).on('change','#PageSize', function () {
//Do something after new value in #PageSize
});
Complete Example with ajax call - this working for my pager - count of item per list:
$(document).ready(function () {
$(document).on('change','#PageSize', function (e) {
e.preventDefault();
var page = 1;
var pagesize = $("#PageSize").val();
var q = $("#q").val();
$.ajax({
url: '@Url.Action("IndexAjax", "Materials", new { Area = "TenantManage" })',
data: { q: q, pagesize: pagesize, page: page },
type: 'post',
datatype: "json",
success: function (data) {
$('#tablecontainer').html(data);
// toastr.success('Pager has been changed', "Success!");
},
error: function (jqXHR, exception) {
ShowErrorMessage(jqXHR, exception);
}
});
});
});