AJAX Sample

How to make the Ajax work - Part 1 XMLHttpRequest


Ajax stands for Asynchronous JavaScript and XML. It is a web development technique for developing rich web applications. Ajax is primarily used on the client site and allows for asynchronous refreshing a part of the web page. The intent is to increase the web page's interactivity, speed, and usability.
The key part of The Ajax technique is asynchronous communication between the web page and the server. The data exchange can be implemented using XMLHttpRequest or IFrame. Since XMLHttpRequest approach is the most popular this article will focus only on this method.

The Ajax technique includes also:
Plain text, XML, preformatted HTML or JSON can be used as data format while communication.
DOM provides an object oriented application programming interface that allows parsing HTML or XML into a well defined tree structure (data model) and operating on its contents.
XHTML (or HTML) and CSS are used in presentation tier for dynamic marking up and styling information.

The example bellows demonstrates how to design and implement basic AJAX component.
You need:
1. Web browser that supports XMLHttpRequest (Microsoft.XMLHTTP or Msxml2.XMLHTTP).
2. Html web page to place the example.
3. JavaScript code that will do the work. (JavaScript XMLHttpRequest)

AJAX (XMLHttpRequest) Web Browser Support

Following web browsers support basic XMLHttpRequest functionality:
Internet Explorer 5.0 +, Mozilla (Firefox) 1.0 +, Safari 1.2, Opera 8.0 +, iCab 3.0b352 +

Sample Web page

We don‘t need anything fancy. Just a basic Html web with some text so we know it works.

<HTML>
<HEAD>
<TITLE>Hello World Page</TITLE>
</HEAD>
<BODY>
Hello World
</BODY>
</HTML>

JavaScript XMLHttpRequest

First we need to write a function which will call the server. It will create the XMLHttpRequest object. Unfortunately each web browser supports the call differently. That is why you will see so many if/else try/catch.

	var xmlHttpReq = false;
        // Mozilla/Safari
        if (window.XMLHttpRequest) {
            xmlHttpReq = new XMLHttpRequest();
            if (xmlHttpReq.overrideMimeType) {
                xmlHttpReq.overrideMimeType('text/xml');
                // See note below about this line
            }
        // IE
        } else if (window.ActiveXObject) { // IE
            try {
                xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
            }
        } 

Then we will open a connection to the web server (strURL — specify address of content you want to load). Third parameter is responsible for type of communication (synchronous — false, asynchronous — true). This is where the A in Ajax comes from.

        if (!xmlHttpReq) {
            alert('ERROR AJAX:( Cannot create an XMLHTTP instance');
            return false;
        }   
		xmlHttpReq.open('GET', strURL, true);
        xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Before sending the request you have to specify the name of a call back function which will receive results from the sever.

        xmlHttpReq.onreadystatechange = function() { 
            callBackFunction(xmlHttpReq); 
        };
        xmlHttpReq.send("");

The callBackFunction is simple. First readyStae is check if the respond from the server was received. Then the http status of the respond have to be ok (200).

    function callBackFunction(http_request) {
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                var responceString = http_request.responseText;
                //TODO implement your function e.g.
                alert(responceString);
            } else {
                alert('ERROR: AJAX request status = ' + http_request.status);
            }
        }
    }

In the summary of first part we will combine all pieces into one HTML page. This small example demonstrates how content of the test.txt file can be loaded and presented using the XMLHttpRequest. See Demo

<HTML>
<HEAD>
<TITLE>Hello World Page</TITLE>
<script language="JavaScript">

    function xmlhttpPost(strURL) {
        var xmlHttpReq = false;
        // Mozilla/Safari
        if (window.XMLHttpRequest) {
            xmlHttpReq = new XMLHttpRequest();
            if (xmlHttpReq.overrideMimeType) {
                xmlHttpReq.overrideMimeType('text/xml');
                // See note below about this line
            }
        // IE
        } else if (window.ActiveXObject) { // IE
            try {
                xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
            }
        }
        if (!xmlHttpReq) {
            alert('ERROR AJAX:( Cannot create an XMLHTTP instance');
            return false;
        }   
        xmlHttpReq.open('GET', strURL, true);
        xmlHttpReq.setRequestHeader('Content-Type', 
            'application/x-www-form-urlencoded');        
        xmlHttpReq.onreadystatechange = function() { 
            callBackFunction(xmlHttpReq); 
        };
        xmlHttpReq.send("");
    }
            
    function callBackFunction(http_request) {
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                var responceString = http_request.responseText;
                //TODO implement your function e.g.
                alert(responceString);
            } else {
                alert('ERROR: AJAX request status = ' + http_request.status);
            }
        }
    }
</script>
</HEAD>
<BODY>
Hello World
<A href="#" onclick="xmlhttpPost('test.txt');return false;">Show content</A> </BODY> </HTML>

How to make the Ajax works - Part 2 multiple XMLHttpRequest

The xmlHttpReq object from previous example is visible globally. Only one instance of callBackFuction can be assigned to the request. Thus if you try to call xmlhttpPost function multiple times one by one for different URLs then it may happen that only the last callBackFunction will be executed. In order to deal with multiple httpRequest you have to make the xmlHttpReq object local. The following example implements xmlhttpPost and callBackFuction as methods and encapsulates in AJAXconnection class.
/** A AJAXConnection class  */
function AJAXConnection(name) {    
    this.className = 'AJAXConnection';
    //alert(this.className + ' ' + name);
    
    /** Default construtor
     *
     * name - div name
     */
    {    
        this.name = name;
    }

    this.xmlhttpPost = function (strURL, functionObj) {
        var xmlHttpReq = false;
        var self = this;
        // Mozilla/Safari
        if (window.XMLHttpRequest) {
            self.xmlHttpReq = new XMLHttpRequest();
            if (self.xmlHttpReq.overrideMimeType) {
                self.xmlHttpReq.overrideMimeType('text/xml');
                // See note below about this line
            }
        // IE
        } else if (window.ActiveXObject) { // IE
            try {
                self.xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
            }
        }
        if (!self.xmlHttpReq) {
            alert('ERROR AJAX:( Cannot create an XMLHTTP instance');
            return false;
        }    
        self.xmlHttpReq.open('GET', strURL, true);
        self.xmlHttpReq.setRequestHeader('Content-Type',
            'application/x-www-form-urlencoded');
        self.xmlHttpReq.onreadystatechange = function() { 
            _callBackFunction(self.xmlHttpReq, functionObj); 
        };
        self.xmlHttpReq.send("");
    }
    
    _callBackFunction = function (http_request, functionObj) {
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                alert(http_request.responseText);
                functionObj.callBackFunction(http_request.responseText);
            } else {
                alert('ERROR: AJAX request status = ' + http_request.status);
            }
        }
	}
}

You may wonder what is the second parameter in the xmlhttpPost method functionObj. The functionObj is any object that implements callBackFunction(string) method. This way you can have multiple implementations of callBackFunction depending on the context. Bellow you can see two deferent implementations of the callBackFunction.

/** A AlertTemplate class */
function AlertTemplate() {	
    this.className = 'AlertTemplate';
    
    /** Call Back Function - called by AJAXAdaptor
     *
     * str - string from XMLHttpRequest
     */    
    this.callBackFunction = function(str) {
        alert(str)
    }    
}

/** A WindowTemplate class */
function WindowTemplate() {	
    this.className = 'WindowTemplate';
    
    /** Call Back Function - called by AJAXAdaptor
     *
     * str - string from XMLHttpRequest
     */    
    this.callBackFunction = function(str) {
        myWindow = window.open("", "tinyWindow", 'toolbar,width=150,height=100')
        myWindow.document.write(str)
        myWindow.document.close() 
    }    
}

Let‘s bring the whole code together and write example utilizing new functionality. Our JavaScript code is growing. I will put all classes from this part to a separate file main.js and link the code from the Html page.

<HTML>
<HEAD>
<TITLE>Hello World Page</TITLE>
<script type="text/javascript" src="main.js"></script>
</HEAD>
<BODY>
<script language="JavaScript">
	// Initialize connections
    var ajaxConnectionAlert = new AJAXConnection('ajaxConnectionAlert');
    var ajaxConnectionWindow = new AJAXConnection('ajaxConnectionWindow');
	// Initialize templates 
    var alertTemplate = new AlertTemplate();
    var windowTemplate = new WindowTemplate();
    
	// Show alertTest.txt file in alert window
    ajaxConnectionAlert.xmlhttpPost('alertTest.txt', alertTemplate);
	// Load the windowTest.txt file to seperate window
    ajaxConnectionWindow.xmlhttpPost('windowTest.txt', windowTemplate);
</script>
Hello World<BR>
<A href="#" 
onclick="ajaxConnectionAlert.xmlhttpPost('alertTest.txt', alertTemplate);return false;">
    Alert Template</A>&nbsp;
<A href="#" 
onclick="ajaxConnectionWindow.xmlhttpPost('windowTest.txt', windowTemplate);return false;">
    Write Template</A>
</BODY>
</HTML>

In this example first two separate AJAXconnection objects are created. Then the AlertTemplate is used to show the content of the alerTest.txt file in the alert window and WindowTemplate is used to print the windowTest.tx file in a new browser window. See Demo