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
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

  • By
    CSS Gradients

    With CSS border-radius, I showed you how CSS can bridge the gap between design and development by adding rounded corners to elements.  CSS gradients are another step in that direction.  Now that CSS gradients are supported in Internet Explorer 8+, Firefox, Safari, and Chrome...

Incredible Demos

  • By
    Create Spinning Rays with CSS3 Animations & JavaScript

    Thomas Fuchs, creator of script2 (scriptaculous' second iteration) and Zepto.js (mobile JavaScript framework), creates outstanding animated elements with JavaScript.  He's a legend in his own right, and for good reason:  his work has helped to inspire developers everywhere to drop Flash and opt...

  • By
    Optimize Your Links For Print Using CSS — Show The URL

    When moving around from page to page in your trusty browser, you get the benefit of hovering over links and viewing the link's target URL in the status bar. When it comes to page printouts, however, this obviously isn't an option. Most website printouts...

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!