Midhat
Midhat

Reputation: 17810

Javascript: Do processing when user has stopped typing

I have a text box on a web page, whose value I want to send to a XMLHttpRequest. Now I want the user to just type the value, without pressing a button. But If i just send the request int he keyboard events, it will fire every time a key is pressed.

So basically I want something liek this

function KeyUpEvent()
{
  if (user is still typing)
    return;
  else 
    //do processing
}

It would be great if the solution could come from plain javascript or mootools. I dont want to use any other library.

Upvotes: 5

Views: 2262

Answers (7)

Venkat D.
Venkat D.

Reputation: 3029

I wrote a custom jQuery event because I use this logic a lot:

jQuery.event.special.stoppedtyping = {
  setup: function(data, namespaces) {
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler);
  },
  teardown: function(namespaces) {
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler);
  },
  keyuphandler: function(e) {
    var interval = 1000;
    var el = this;

    if (jQuery.data(this, 'checklastkeypress') != null) {
      clearTimeout(jQuery.data(this, 'checklastkeypress'));
    }

    var id = setTimeout(function() {
      jQuery(el).trigger('stoppedtyping');
    }, interval);
    jQuery.data(this, 'checklastkeypress', id);
  }
};

You can use it like this:

$('input.title').bind('stoppedtyping', function() {
  // run some ajax save operation
});

For some reason I could never get it to work with .live( ... ). I'm not sure why...

Upvotes: 0

Christian C. Salvadó
Christian C. Salvadó

Reputation: 827366

I always use this simple function to handle a timer, that will fire a callback function, after the user has stopped typing for a specified amount of time:

var typewatch = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  }  
})();

Usage (example with MooTools):

$('textInput').addEvent('keyup', function(e){
  typewatch(function () {
    // executed only 500 ms after the last keyup event
    // make Ajax request
  }, 500);
});

The main difference between this solution and solutions from other answers is that all the timer logic is handled by the typewatch function itself, the event handler doesn't need to know anything about the timer, it just invokes the function. Also, there are no global variables to take care (the timer id is not stored on a global variable).

Upvotes: 5

Avi Flax
Avi Flax

Reputation: 51819

Basically, you want to start a timer on KeyUp, and when KeyUp starts again, reset the timer. When the user stops typing, the timer runs out, and your request can go at that point.

Example:

var timout_id;

function keyup_handler(event) {
  if (timout_id) {
    clearTimeout(timout_id);
  }

  timout_id = setTimeout(function(){
    alert('sending data: \n' + event.target.value)
  }, 800);
}

Just attach the function to the input using your preferred method, and replace the alert with your preferred action.

Of course there are many ways you could generalize this approach and make it more reusable, etc, but I think this illustrates the basic idea.

Upvotes: 9

user216441
user216441

Reputation:

var keyTimer;
function onKeyUp(){
clearTimeout(keyTimer);
setTimeout(stoppedTyping,1500);
}
function stoppedTyping(){
// Profit! $$$
}

EDIT: Damn ninjas

Upvotes: 1

nicerobot
nicerobot

Reputation: 9235

Use onBlur and maybe an onKeyDown to check for the user pressing the return/enter key.

Upvotes: -1

Will
Will

Reputation: 5537

You never know when a user is really "finished" typing. The user might take a sneeze break, or a stretch break, or a coffee break, and then continue typing.

However, if you're implementing something like an autocomplete mechanism, you can set a timer (cf. window.setTimeout(...)) to see if the user hasn't typed anything in a certain amount of time. If you get another key-up event while the timer is running, you can start the timer over.

Upvotes: 2

cmptrgeekken
cmptrgeekken

Reputation: 8092

The way this is usually done is by restarting a timer on the keyup event. Something like this:

var keyupTimer;
function keyUpEvent(){
   clearTimeout(keyupTimer);
   keyupTimer = setTimeout(sendInput,1000); // will activate when the user has stopped typing for 1 second
} 

function sendInput(){
    alert("Do AJAX request");
}

Upvotes: 10

Related Questions