Delay AJAX Searches with JavaScript’s setTimeout

By  on  

I was recently creating a custom Dijit widget that required that a list get filtered during each keystroke instead of using the usual "Submit" button.  The problem I ran into (and had anticipated) was that each keystroke made the list flicker and fire off numerous AJAX requests.  The normal flow was:

D
Da
Dav
Davu // Oops, mistyped!
Dav
Davi
David
David_ // Space
David_W //...and so on

Users that type quickly don't need a list filtered during every keystroke -- that's a waste of client-side processing.  The simple solution is to employ JavaScript's native setTimeout method to delay searches until a given idle-time has passed.  Users who type quickly thus wont bog down the page.

// Add an onChange to the textbox to listen to typing/changes
this.findTextbox.lastValue = "";
var timeout;
dojo.connect(this.findTextbox,"onKeyUp",this,function(){
	// Only fire change if value has changed
	var value = this.findTextbox.get("value");
	if(value != this.findTextbox.lastValue) {
		// Save the "last" value
		this.findTextbox.lastValue = value;
		// Delay before search in the case of typing
		if(timeout) { clearTimeout(timeout); }
		// Start new time out
		timeout = setTimeout(function() {
			// Do the search!
			console.warn("Doing search for " + value + ", time waited");
			// Process....
		},this.findKeyDelay);
	}
});

It's important to store the last value of the input so that "useless" keys like SHIFT, CONTROL, and others don't trigger a restart of the timer.  If the key does change the value of the input element before the timer is met, the timer is clear and restarted!  You'll notice that I do not ensure that a value is present -- that's because I want the field to return all results if the user filters something and then deletes the input!  This type of timer solution will save loads of unwanted processing on both the client and server sides!

Recent Features

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

  • By
    Responsive Images: The Ultimate Guide

    Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today's websites and devices become ever more varied, a plethora of responsive images...

Incredible Demos

  • By
    Making the Firefox Logo from HTML

    When each new t-shirt means staving off laundry for yet another day, swag quickly becomes the most coveted perk at any tech company. Mozilla WebDev had pretty much everything going for it: brilliant people, interesting problems, awesome office. Everything except a t-shirt. That had to change. The basic...

  • By
    Animated AJAX Record Deletion Using jQuery

    I'm a huge fan of WordPress' method of individual article deletion. You click the delete link, the menu item animates red, and the item disappears. Here's how to achieve that functionality with jQuery JavaScript. The PHP - Content & Header The following snippet goes at the...

Discussion

  1. hi david! just curious, why you don’t provide any demo page in this post..?

    • I didn’t include one because the idea of it is simple:

      1. When a key is pressed, and the string is longer than minimum length, start a timeout

      2a. If the value is still the same after that time out, run the search

      2b. If the value isn’t the same, clear the timeout and start it again.

      It’s more the concept that the execution. An example wouldn’t explain much more.

  2. Great tip! What value do you suggest setting the delay to?

    • I don’t have a steadfast, scientific number but I think 500 ms is a good number.

    • Check that — 200 ms is a better one. :)

  3. false

    hi David ! i have tried it at work, but i had prefer to use a periodical method instead of the “onKeyUp” event for checking if the value has changed or not. I think it’s usefull for copy/paste, what do you think about it ?

    I’ve tried it here : http://www.rtl.fr/recherche (french website)

    thanks!

    • Marko

      Even better solution is that onkeyup, oninput and onpaste events you just blur and focus the input element. Like that onchange event is fired, which you can use for checking.

  4. Dan

    This sort of technique will become increasingly important because, I predict, more and more pages will use typeahead not only for search suggestions, but also to update actual page content. I already see examples of typeahead on ecommerce sites showing suggested products as a user types a search phrase.

  5. Shane Burgess

    I had to do this with an App that I was writing as well. I toss a 1 second timeout on it and it improved the slickness 100 fold. :)

    • Yep, I’ve found that I’m doing this more often than not.

  6. jeff

    This idea has a little problem attached to it.
    I’m not sure if you noticed.

    Lets say you set findKeyDelay to 1000ms.
    Lets say, user types word “audi” and typing takes less than 1 sec.
    In such case your search may get stuck …

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!