Reputation: 13
I have a registration form, and i want to dynamically check for the submitted user name availability using AJAX.
So far i've made a input field with an OnKeyUp event which calls a function named reg_un_check();
Problem is, at the current setting, which works fine, the function runs every key stroke.
I wanna make some kind of "delay" between the keystrokes and the function call to let the user finish typing and save some bandwidth.
I tried using SetTimeout()
but it only delays the time it takes between the AJAX requests.
This is what i've made so far:
Input Field:
<input type="text" value="user name" id="reg_un" onclick="reg_un_in()" onblur="reg_un_out()" onkeyup="reg_un_check()">
<div class="alerts" id="reg_un_alert"></div> // div that pops out if the UN isnt valid
<div class="reg_unc" id="reg_unc_alert"></div> // div that pops out when its checking for the availability
The AJAX function:
function reg_un_check(){
if(reg_un.value.length > 1){
$("#reg_un_alert").slideUp(150);
var un_data = "un=" + reg_un.value;
$("#reg_unc_alert").slideDown(150,function () {
var un_check = setTimeout(function(){
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
reg_unc_alert.innerHTML = xmlhttp.responseText;
}
else{
reg_unc_alert.innerHTML = "checking for availability...";
}
};
xmlhttp.open("POST",'un_check.php',true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(un_data);
},2000);
});
}
else{
$("#reg_unc_alert").slideUp(150);
reg_un_alert.innerHTML = "the user name must be at least 2 characters long";
$("#reg_un_alert").slideDown(150);
}
}
Can anyone suggest a different or a better way to do that? Thanks.
Upvotes: 0
Views: 107
Reputation: 1941
It's a very common concept in javascript, called debouncing, lodash library has it: https://lodash.com/docs#debounce
A simple way to make it your self is like this:
var timeoutId;
function debounceFunction() {
clearTimeout(timeoutId); //no worries if timeoutid is undefined
timeoutId = setTimeout(delayedWorkFunction, delay);
}
A more complicated way, but a more generalized way to do it is to have a function that receives a function and a delay, and returns a function that on invocation will execute that function with the delay and cancel calls that were made before the delay has passed (i.e. what lodash debounce function does).
function debounce(cb, delay) {
var tId;
var retFunc = function() {
clearTimeout(tId);
setTimeout(cb, delay);
}
return retFunc;
}
function work() {
//your logic here
}
var delayedWork = debounce(work, 150);
//now calling delayedWork will do what you want
Hope I didn't over complicate it.
Upvotes: 1