views:

181

answers:

3

Disclaimer: I am anything but a Javascript expert, so I'm not even sure if I'm approaching this correctly...

I want to be able to trigger an event in Javascript, but be able to cancel that event if another event occurs. So, what I'm looking to accomplish is:

  • User begins typing in a text box.
  • When textbox contents change, trigger an event that makes an AJAX call
  • BUT, if the user keeps on typing, cancel that event, because I don't want to do the query until after they are finished typing

i.e. If the user is typing "foobar" in, I don't want to do the AJAX search until they're done typing. There is no reason for me to do:

AJAX("f") and then AJAX("fo") and then AJAX("foo") and then AJAX("foob") ...

when I could have just done a single call when they were done typing AJAX("foobar")

... am I making any sense? Or is there a better way to approach this?

Oh, and then the kicker: I'd like to avoid JQuery/Prototype, and do this with just straight javascript... yeck!

+3  A: 

What you want to do on keypress is

if(myTimeout)
   window.clearTimeout(myTimeout);

var myTimeout = window.setTimeout(function() {
   alert('one second has passed without any keypress');
}, 1000);
David Hedlund
+2  A: 

If you don't want to use a framework, you may want to look at ta standalone AJAX library like Matt Kruse's .

I think it is possible to abort an AJAX request. However, starting and aborting requests on each keypress sounds horrible to my ears.

I would take a different road:

  • Wait some time before sending out the request (check whether the input's value has changed since then, and if it hasn't, make the request)

  • Let each Ajax request go through successfully, but mark each one as to which input value it was made for. Only when the input's current value, and the marker of the request, are identical, do your stuff and display the results. Otherwise, you quietly drop the results.

Pekka
Sorry, but your approach would result in way too many requests. A timeout approach is far more economical. Had to downvote this because it's simply cumbersome.
Tom Bartel
A timeout is what I am recommending. The timeout solution above does not yet tell how to deal with the user starting to type again after 1000ms.
Pekka
True, I was too harsh. Removing downvote. However, your approach still executes a lot of functions that are not necessary. In my view, cancelling the timeout on subsequent key press events is smarter.
Tom Bartel
Hm, "Vote too old to be changed." I can undo my downvote only if you edit your answer.
Tom Bartel
Edited. I'm not sure whether the approach executes too many functions - if a user stops typing, a Request is going to be sent. Do you want to abort each of those if the user starts typing while the request is out? I'm in favour of letting them run through once they're started, instead of aborting them, that's the only difference.
Pekka
A: 

something like this:

var to = null; //the timeout
function doStuffWithContents(){
   //code that does the ajax goes here
}

document.getElementById('the_textarea').onkeyup = function(){
  if (to) {
    window.clearTimeout(to);
  }
  to = window.setTimeout("doStuffWithTheContents()",1000); //1000 = one second
}
Ramuns Usovs