Alex
Alex

Reputation: 13

Running a function after a set amount of time

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

Answers (1)

PiniH
PiniH

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

Related Questions