How To - Throttle Ajax Requests

Needs Cleanup

This article needs cleanup to meet our writing standards:

  • Spelling and punctuation
  • Code clarity
  • Avoid first person

Can you help? Click edit below!

Although i call it Ajax Throttling i dont think this is the technical term for it. Basically what we want to achieve in an ajax auto completer is to send the request only when the user input has stopped - Not on every keypress, so we have to adjust our code in some ways to achieve this

I will try to be as commenting as possible to help with my often messy coding !!

var callbackElement             = 'suggestiveResults'; // set the element that recieves the responseText
var callbackElementClass     = 'suggestResults';
 
var functions = {
    primeSuggest : function(e) {
        clearTimeout(timeouts); 
    timeouts=window.setTimeout(
            function() {
            functions.suggest(e,this);                 
        },
            900
        );        
    }
}

Okay the above creates the priming function for the suggestive, you can easily do it without object notation, i just happen to be in an object notation phase !!..

It starts by clearing any timeouts the function may have created and creates a new one @ 900 MS - this is enough time to simulate a keypress

suggest : function(e,to) {
    if ($(e).value.length<3) {
        // make sure the string length of the input is over 3 chars 
        if ($(callbackElement)) {
            /** if the string length is less than 3 and 
             *   the element exists (when someone 
             *   deletes charachters the element 
             *   might stilll display so remove it
             */
            $(callbackElement).remove();    
            return;
        }
    }
    if($(e).value.length>=3) { // make 
        if(!$(callbackElement)) { 
            // if the element doesn't exist then create it
            var offSet=$(e).cumulativeOffset(); // get its position on the page (x/y)
            var newx=offSet[0]; // left
            var newy=offSet[1]+23; // top -- you can remove the +23 - this was just for my example 
                                   // to make it appear 23 px below the element as my element
                                   // as a background image with an arrow pointing to the input element
 
            /**
              * Now create a new element ... most of the styling can be done with CSS 
              * except the top & left position of it which has to be inline .. this is
              * a browser safe way of inserting the element for the results without
              * cross browser css quirks on positioning and defers the need for
              * display:none on an element below the input element ... 
              * The width is the same width as the input element 
              * - this can also be set in the css class
              */
 
            var suggestiveElement=new Element('div'{
                'id':callbackElement,
                'class':callbackElementClass,
                'style':'position:absolute;width:297px;overflow-y:auto;top:'+newy+'px;left:'+newx+'px;z-index:9999;font-size:13px;'
            });
            $$('body')[0].insert(suggestiveElement); // insert it into the DOM
        } 
        /**
          * do the Ajax.Updater
          */
        var suggestiveElement=$(callbackElement);
        var req=new Ajax.Updater(suggestiveElement, '/SuggestiveSearch', {
            evalScripts:    true,
            method:         'post', 
            parameters:   {    
                text:$(e).value
            }
        });    
        req=null; // null the object to save the memory and unload around 40% of the memory loaded for this request
    } 
}

The above code is well commented and should be pretty easy to follow. It handles all of the Requesting and checking of string lengths and creates the element for the callback responseText to be placed in.
Event.observe(window,'load', function() {
    Event.observe('search', 'keyup', function(e) {
        functions.primeSuggest(this.id);
    });
});

The above tells the DOM to observe $('search') for key up, on keyup it fires primeSuggest. Prime suggest sets a timeout on the next part of the script @ 900 MS, basically it will start a timer to send the data to the server in 900 MS provided that the string is over 3 chars… However we do not want to send a request on each keypress as this is a heavy server load so …. the script is interrupted by a keypress - resetting the timeout if you like to another 900 MS everytime a key is pressed .. if no key is pressed in 900 MS then the value of $('search') is sent to the server where your script will process it however you want it to - the main focus being on the timeout that is interupted and cleared should a key be pressed …. its how google suggest works but alot simpler !!!

And the HTML could not be simpler

<input type="text" id="search" name="search" autocomplete="off" value="Search...."/>

Notice `autocomplete="off"`

While this is not W3c complient it will stop the browser suggesting anything you have previously put into the $('search') element .. this is done because the suggested browser results allways sit atop of the ajax request results - no matter what z-index you apply to the reposnse Element.

Hope you can put this to good use and your servers feel the benefits of this..

In my next how to i will be showing how to save memory when ajax requesting

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License