References Used


AJAX Essentials


Operations with Each Ajax Step


An Ajax Request Library

The process of launching an Ajax request and then processing the response can be tedious, so I have prepared an Ajax library that you can use. The library contains two functions:

  1. ajaxRequest(send_type, url, params, callback): creates and returns an ajax object (i.e., an XMLHttpRequest object). This is the function you will call to create an ajax object. The four parameters are as follows:

    The callback function takes no arguments but you can get around this restriction by adding additional properties to the ajax object. Since the callback function is made a method of the ajax object, it will be able to access these properties by prefixing the properties with the this keyword.

  2. ajaxResponse(): This is an internal function that you should never call. The ajaxRequest function makes ajaxResponse be the function that gets called by the onreadystatechange event. ajaxRequest ensures that your callback function gets called when the server has completed its processing of your request. ajaxRequest makes ajaxResponse be a method of the ajax request object so that ajaxResponse handles the correct ajax call. Since the onreadystatechange event does not pass any parameters to the function it calls, it is necessary to make the ajaxResponse function be a method of your ajax object, so that it can access the appropriate callback function.
If you use this library, you can have easily have multiple Ajax requests pending simultaneously, and ensure that the correct callback function gets invoked for each one (e.g., for different quotes on a financial web site).


Changing HTML Content on the Client Side

Frequently an ajax response will need to change the content of html elements. Javascript provides a way to do this by representing each html page as a tree encapsulated in an HTML DOM object. The only real difference is that the HTML DOM provides a few additional convenience methods not offered by the XML DOM that are made possible by domain-specific knowledge about HTML. For example, HTML supports ID and NAME tags, and so the HTML DOM provides convenience methods named getElementByID and getElementsByName.

Thus to modify an html element, one should first retrieve the appropriate element using an HTML DOM query command. To retrieve the element, you should use getElementById if the html element is identified with an id attribute and getElementsByName if the html element is identified with a name attribute. You can then modify the element's value by modifying its innerHTML property. Thus one might write:

document.getElementById('ibm').innerHTML = 98.46; // element uses id
document.getElementByName('ibm').innerHTML = 98.46; // element uses name
A more standard DOM-oriented way to perform the element change would be to traverse the DOM tree. The html content is in the first node of a text element and can be accessed via the nodeValue property:
document.getElementById(ibm').firstChild.nodeValue = 98.46
Note that if the document were an XML document rather than an html document, you would have to use the second approach, because the innerHTML property would not be defined for nodes in an XML document. Also note that unlike the XML DOM, you can directly modify the nodeValue rather than having to replace the element.


Returning JSON Objects From the Server

If you are using PHP, you can encode your output as a JSON string using json_encode. For example:

header("Content-Type: application/json; charset=UTF-8");
$jsonArray = array('insertionSuccess' => $successFlag,
                   'errorMessage' => $errorMessage);
echo json_encode($jsonArray);
The header function produces a statement in the string that identifies it as a json string. The header function should be called exactly once, before any json strings are emitted.

On the client side, your callback function might look like:

function responseHandler() {
    var result = JSON.parse(this.responseText);
    if (this.textstatus == "success" && result['insertionSuccess']) {
        ... process result ...
    }
    else {
      alert("failed to update section\nerror message: " + result['errorMessage']);
    }
}
If you need to return multiple tuples from an SQL query, then you will need to use sub-arrays for each tuple since you can only return one JSON object, which is constructed from the top-level array. For example:
$result = mysqli_query("SELECT name, major, gpa FROM student"); 
$jsonArray = array();
$i = 0;

while($row = mysqli_fetch_array($result)) {
    $jsonArray[$i] = array("name" => $row['name'],
			   "major" => $row['major'],
			   "gpa" => $row['gpa']);
    $i = $i + 1;
}      
echo json_encode($jsonArray);

Returning XML Documents from the Server

These days it is typically easier to return information from the server side using JSON. However, if you are dealing with legacy code, or if you already have a document encoded in XML, or if you are manipulating a document on the server-side, then your server side code may return an XML document instead of a JSON object. This section describes how you deal with XML documents on the server-side. There are several issues you need to be aware of in order to make your server-side script work in the way you anticipate:

  1. If you want to read an XML document then its file permission must be set to be world readable. If you also want to be able to update the XML document, then the file permission must be set to be both world readable and writeable.

  2. You should use the DOM parser to modify the contents of an XML file. You will need to use the createElement and replaceElement commands to do so. While you should be able to modify text content using the simpleXML parser, it does not seem to work correctly in practice.

  3. Once you have modified your XML content, you will want to save it. Unlike the simpleXML parser, the DOM parser does not provide a command that both converts the XML document to a text string and writes it to a file. Instead it only provides a command to convert the XML document to a text string. You will need to either use fopen/fputs/fclose or the simpler file_put_contents function to actually save the document. For example:
      $xmlDoc->formatOutput = true;
      file_put_contents("quotes.xml", $xmlDoc->saveXML());
    

  4. If you want your PHP script's output to be treated as an XML document by the client-side brower, then you need to write out a header that tells the browser that the document is an XML document. You can write out an appropriate header using PHP's header command:
      header('Content-Type: text/xml; charset=utf-8');
    
    The important information in this header is the "text/xml" content-type, which tells the browser to treat this document as an XML document.

    If you fail to have your PHP script write out this header information, then the ajax request object on the client-side will have its responseText field set, but its responseXML field will be set to null.

  5. In addition to saving an XML document to a file, you may want to write out the XML document to the client. If you want to send the XML document to the client, use the document's saveXML command to generate a text string and then make sure you use PHP's echo or print commands to print the string returned by the saveXML command. If you do not do so, then the string will not be included in the XML document returned to the client. For example, write this code:
      echo $xmlDoc->saveXML();
    
    instead of this code:
         // missing echo command means that the text string returned by saveXML
         // will not be inserted into the XML document returned to the client
         $xmlDoc->saveXML();
    


Examples

In class we will do a more complicated example that involves being able to vote for your favorite color and see the counts for each color be updated in real-time. To do this we will actually have to write both client-side and server-side scripts.