• Using Ajax Without Server-Side Scripting

    May 23 2006

    Ajax, by which I mean XMLHTTPRequest, is almost always used with some sort of server platform, such as PHP or Java, usually to retrieve data from a database. This might scare off some people from using XMLHTTPRequest, especially those who don't have the ability or knowledge to do server-side scripting. This is fine. You can actually do some things without it. I'll do a simple example with populating select boxes.

    HTML

    First off, we need some HTML to work with. For this example, we'll have two select boxes. When the first one changes, we want the second one to fill up with data from the server.

    <form>
        <select id="one">
            <option value="">Please choose one...</option>
            <option value="colours">Colours</option>
            <option value="numbers">Numbers</option>
            <option value="letters">Letters</option>
        </select>
    
        <select id="two">
        </select>
    </form>

    Data

    Now we need some data files. Before I begin, I'll just mention that there are several ways to get back data from the server. Some people use XML, others use something called JSON which stands for JavaScript Object Notation, you can also get back raw HTML or JavaScript, and then there are other ways as well. For this example, I'm going to use JSON because it's pretty simple. You can do really advanced stuff with JSON, but I'm just going to use a JavaScript array. I'm going to create a file for each select option in select box 'one'. Each file will have an array of values to put into select box 'two'.

    Update: technically this isn't JSON, even though it works. More information here.

    select_colours.js:
    ['red','orange','black','purple','yellow','forest green']
    
    select_numbers.js:
    ['3242','84930','12','5433344','8837845','1980']
    
    select_letters.js:
    ['G','f','s','j','P','m']

    This example isn't using a lot of data, but chances are in real life, you wouldn't use Ajax unless you had a lot of extra data to get back from the server. Otherwise, it wouldn't be worth going to the server to get the data, and you might as well just put the data directly into the page.

    JavaScript

    Any usage of XMLHTTPRequest starts with a function similar to this. It finds the XMLHTTPRequest object in a way that works across all browsers, then it sets up a callback function to do the dirty work, and sends the request to a url:

    function httpRequest(url, callback) {
        var httpObj = false;
        if (typeof XMLHttpRequest != 'undefined') {
            httpObj = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try{
                httpObj = new ActiveXObject('Msxml2.XMLHTTP');
            } catch(e) {
                try{
                    httpObj = new ActiveXObject('iMicrosoft.XMLHTTP');
                } catch(e) {}
            }
        }
        if (!httpObj) return;
    
        httpObj.onreadystatechange = function() {
            if (httpObj.readyState == 4) { // when request is complete
                callback(httpObj.responseText);
            }
        };
        httpObj.open('GET', url, true);
        httpObj.send(null);
    }

    Now, we'll add three more JavaScript functions. First, we'll add a callback function to take our JSON data and put it into the select box:

    function fillSelect(JSON) {
        var selectTwo = document.getElementById('two');
       	
        // clear out existing options
        while (selectTwo.options.length) {
            selectTwo.options[0] = null;
        }
    	
        // fill with new options from JSON array
        var data = eval(JSON);
        for (var i=0;i < data.length;i++) {
            selectTwo.options[selectTwo.options.length] = new Option(data[i]);
        }
    }

    Notice we use the eval() function to turn our JSON text string into a real JavaScript object.

    Next, we'll add an event handler function to react when the first select box changes. This will send off the actual XMLHTTPRequest:

    function onSelectChange() {
        // get the value of the selected option in select box 'one'
        var selectOne = document.getElementById('one');
        var selectedOption = selectOne.options[selectOne.selectedIndex].value;
    
        if (selectedOption != "") {
            // find the appropriate javascript file
            httpRequest('select_' + selectedOption + '.js', fillSelect);
        } else {
            // empty the options from select box two
            fillSelect('[]');
        }
    }

    Lastly, we need to assign the onSelectChange() event handler to the select box. We'll do this in a window.onload function:

    window.onload = function() {
        var selectOne = document.getElementById('one');
        selectOne.onchange = onSelectChange;
    }

    Conclusion

    There you have it! If you want to see it in action, click on the files listed below:

  • Comments

    1. seyhan ersoy at 9:41am on July 10, 2006

    It is well written and very informative. I like it.
    Thanks.

    2. Sreenivas Tirumalasetty at 6:17am on July 17, 2006

    It is very good and simply understanding and very usefull. I like this artlcle.
    Thanks.

    3. Mark at 4:00pm on August 1, 2006

    Well written article; easy to understand explanation of JSON. Thanks.

    4. Visitor at 2:00am on October 24, 2006

    Thank-you for the easy to understand method, it has been very helpful to see the request and responce laid out simply and not buried in wrappers or libraries!

    One question though... Do we really need to create the XMLHttpRequest object every time we change a selection? Can't we create the object one time and use it over and over?

    Thank-you

    5. Jesse Skinner at 7:57am on October 24, 2006

    Sure, you can reuse the object. I think it can become problematic if the user tries to have 2 requests going on at the same time. I'm not 100% sure, but I remember problems with the 2nd transaction cancelling the first.

    Try it out, see how it performs, and let us know.

    6. Visitor (Bill) at 2:33pm on October 25, 2006

    Thanks Jesse,

    My application makes requests on a timed basis (250mS) so there are a ton of requests being made. I watched IE6's memory usage while the script was running and it was really eating up the memory and the displayed responses really started to slow down. I did find an article on reusing the request object-

    http://radio.javaranch.com/pascarello/2006/03/30/1143735438047.html

    I'm going to try and see if this may fix the problem I am having. My application only requires a single request object at a time, it just needs to reuse it frequently.

    7. James at 4:09am on February 28, 2007

    Great tutorial!

    Any pointers on how to adapt this to read from xml files instead?

    Thanks.

    8. Harini at 3:14pm on April 23, 2007

    Hi,

    I am trying to render an applet inside my webpage but unfortunately everytime  I load the applet the page gets resubmitted and that causes some problem. So I tried using AJAX to invoke the applet creation so that the loading of the same would not cause its resubmission. Now the server side scripting of the same was javascript, and the data is returned using "document.write" method. Can you tell me how to access the value of the document.write alone and not the entire html response string?

    Eg: server side is say
    <html><script>document.write('hello');</script></html>
    My httobject.responseText in onLoad will have the entire html document whereas I would need only the return value , i.e "hello".

    Any ideas, please?

    9. Srinivas Grandhi at 2:32pm on July 17, 2007

    Nice and simple example. It was very useful in understanding the client side of the process. Thanks!!!

    10. Krips at 7:18am on July 18, 2007

    I was actually searching for Server side scripting using JavaScript, I think this example of yours will help me in better understanding of Server side scripting.
    Thanks Buddy!!!!

    11. avinash at 3:21am on July 2, 2008

    good tutorial, liked it very much....

    Commenting is now closed. Come find me on Twitter.