Set a timeout and delay a function call with JavaScript (jQuery)

This is how you can on change and on key press or actually Key up event call an action after a certain amount of seconds, in this case 2 sec (2000 milliseconds). Here I use it on a textarea in Drupal 6 with no text editor. I want to call a function that calculates estimated execution time based on given number of rows in the textarea.

First the jQuery script in my hook form

<?php
  $js
= '$("#edit-urlsToCheck").change(function() {
            sendUrls();
        });
       
        $("#edit-urlsToCheck").keyup(function() {
          clearTimeout($.data(this, "timer"));
          var wait = setTimeout(sendUrls, 2000);
          $(this).data("timer", wait);
        });
       
        function sendUrls(){
            $.post("tool_avgtime/null", $("#edit-urlsToCheck").serialize(), function(data) {
                    $("#urlsToCheck-row-count").html(data);
            });
        }
        '
;
 
 
drupal_add_js($js, 'inline', 'footer');
?>

Then hook menu

<?php
  $items
['tool_avgtime/%'] = array(
     
'page callback' => 'tools_avg_time',
     
'page arguments' => array(1),
     
'access arguments' => array('access tools'),
     
'type' => MENU_CALLBACK,
  );
?>

Then the returning function

<?php
/**
 * AHAH returns estimated execution time
 *
 * @param unknown_type $URLs
 */
function tools_avg_time($URLs = FALSE){
   
    if (!
$URLs OR $URLs == "null") {
       
$URLs = $_POST['urlsToCheck'];
    }
   
   
$URLs = array_unique(array_filter(explode("\n", $URLs)));
   
   
$nbr = count($URLs);
   
   
$aet = variable_get("tools_avg_exe_time", 0);
   
   
$eta = round($nbr*$aet, 1);
   
    if (
$eta > 60) {
       
$eta = round(($nbr*$aet)/60, 1);
       
$unit = "minutes";
    }else{
       
$eta = round($nbr*$aet, 1);
       
$unit = "seconds";
    }
   
    print
t('Estimated execution time:')." $eta $unit for $nbr URL:s";
    exit;
}
?>

The form item receives the jQuery respons ithe div created in the suffix of the form item

<?php
  $form
['urlsToCheck'] = array(
   
'#title' => t('Check redirects'),
   
'#type' => 'textarea',
   
'#value' => !empty($opt['urlsToCheck']) ? $opt['urlsToCheck'] : '',
   
'#description' => t('URLs separated with a row break. (must begin with http:// or https://'),
   
'#suffix' => "<div id='urlsToCheck-row-count'></div>",
  );
?>
Knowledge keywords: