Getting Started With AJAX
November 19, 2008 Paul Tuohy
In this article, we will see how AJAX works by looking at a simple example of using AJAX to retrieve the description (from the server) for a code entered on a Web page. Remember one of the main benefits of AJAX is that communication between the Web page and the server is asynchronous. This means that the Web page may be updated with information from the server without the user having to click any submit button. An Example Figure 1 shows the Web page initially displayed to the user, and it also shows the contents of the page after the user has entered a product code and the server retrieved a description.
The example has two HTML pages: ajax1.html is the requesting HTML document; and ajax2.html is the response document that is returned to the ajax1.html requesting document. It also has one RPG CGI program: AJAX2 processes the request from the browser and returns the product description. The RPG CGI program makes use of CGIDEV2. AJAX and RPG Programming: The XMLHttpRequest Object AJAX is implemented through JavaScript’s XMLHttpRequest object, which provides a set of methods (functions) and variables that allow a Web page to send data to and receive data from a server. To enable an AJAX conversation between the browser and the server, your Web page must first instantiate an XMLHttpRequest object. You make use of the XMLHttpRequest object’s open() and send() methods to “call’ an RPG program; the request is in the same format of any CGI request on a hyperlink or in a form. The XMLHttpRequest object’s onreadystatechange, readyState, status, and responseText variables are used to determine the data received from the server, and you code a function to process it. This complete process of issuing the call and receiving and processing the returned data is asynchronous. The RPG program is like any other CGI program. The only difference is in the format and content of the data returned. But you will find yourself writing programs in a different way to cater for multiple AJAX calls. (E.g., the same program may be called multiple times performing a different field validation on each call.) The HTML Documents The following code shows the HTML for ajax1.html, the requesting document: <script TYPE="text/JavaScript"> <!-- Definition of JavaScript functions createXMLHttp() & callServer() here --> </script> <html> <head> <title>Simple example of AJAX at Work</title> </head> <body> <a href="ajax0.html">Menu</a> <center><h1>Ajax at Work!</h1> <h2>Simple example of AJAX at Work</h2></center> <p>Enter a valid product code (0000001) and the description is displayed </p> <table border=0> <tr><td>Product Code: <input type="text" id = prodcd name=prodcd size=7 maxlength=7 onChange="callServer()"> </td> <td><div id="prodds" ></div></td> </tr> </table> </body> </html> The main points to note are:
The next piece of code shows the HTML for the content returned by the RPG program on the AJAX call. In the example below, the program returns a table with one row and one cell containing the product description. This is a standard CGIDEV2 document with a section named “top” and a single variable named “prods”. Even though it is not a new page that displays, the Content-type is still required at the start of the page. /$top Content-type: text/html <table border=0> <tr><td>/%prodds%/</td></tr> </table> This table will be placed in the <DIV> identified by the “prods” id in the first piece of code. The RPG Program The next code shows a standard CGIDEV2 program that:
This example shows ajax2.html, the RPG program that returns the description: H Option(*SrcStmt:*NoDebugIO) H DftActGrp(*No) ActGrp('AGCGI') BndDir('ALLBNDDIR') FProduct1 IF E K Disk ExtFile('AJAXLIB/PRODUCT1') /Copy PROTOTYPEB /Copy USEC D SavedQryStr S 2000A Varying /Free gethtmlIFS('/ajaxdocs/ajax2.html'); If ZhbGetInput(SavedQryStr: QUSEC) > 0; ProdCd = ZhbGetVar('prodcd'); Chain ProdCd Product1; If Not %Found(Product1); ProdDs = '*** Product Not Found ***'; EndIf; updHTMLvar('prodds':prodds); wrtsection('datarow'); EndIf; wrtSection('top *fini'); Return; /End-Free The AJAX Bit! Now we come to the crunch, the two JavaScript functions that will do all of the work: createXMLHttp() and callServer(). These are the two JavaScript functions coded between the script tags at the start of the ajax1.html. For completions sake, the next piece of code shows an example of a function to instantiate an XMLHttpRequest object. Usually you won’t have to code this, you will simply use the one included in whichever AJAX toolbox or framework you happen to download. function createXMLHttp() { if (typeof XMLHttpRequest != "undefined") { return new XMLHttpRequest(); } else if (window.ActiveXObject) { var aVersions = ["MSXML2.XmlHttp.5.0", "MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp", "Microsoft.XmlHttp"]; for (var i = 0; i < aVersions.length; i++) { try { var oXmlHttp = new ActiveXObject(aVersions[i]); return oXmlHttp; } catch (oError) { } alert("Could not connect"); } } throw new Error ("Could not create an XMLHttp object"); } This is a great example of the “which browser” problem faced by Web developers. The exact object used depends on which browser is being used. The XMLHttpRequest object is supported by all current browsers, but in releases of IE prior to version 7, support is through a Microsoft proprietary interface (ActiveX objects); luckily that interface is 100 percent compatible with XMLHttpRequest. At last, the final piece of code shows the callServer() function that does all the AJAX work: function callServer() { (1) var prodcd = document.getElementById("prodcd").value; (2) var url = "/ajax/AJAX2?prodcd=" + escape(prodcd); (3) var xmlHttp = createXMLHttp(); (4) xmlHttp.open("GET", url, true); (5) xmlHttp.onreadystatechange = function() { (6) if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { document.getElementById("prodds").innerHTML = xmlHttp.responseText; } else { alert("An error occurred trying to contact the server."); } } } (7) xmlHttp.send(null); } The main points to note (refer to the numbers in the above code):
Obviously, the real work is done in the final step when the data returned from the server is processed (in this case, the data is simply some HTML text). The readyState may have a value of 0=Un-initialized, 1=Loading, 2=Finished Loading, 3=Retrieving Data or 4=Completed. The status may be one of the standard server status codes: 404=Not Found, 501=Not Authorized, etc. That’s the Gist! Hopefully this gives you some idea of how easy it is to use AJAX. When it comes down to it using AJAX is really about mastering Javascript in order to “communicate” with the Web page. The server side of the process is very simple. Paul Tuohy is CEO of ComCon, an iSeries consulting company, and is one of the co-founders of System i Developer, which hosts the RPG & DB2 Summit conferences. He is an award-winning speaker who also speaks regularly at COMMON conferences, and is the author of “Re-engineering RPG Legacy Applications,” “The Programmers Guide to iSeries Navigator,” and the self-study course called “iSeries Navigator for Programmers.” Send your questions or comments for Paul to Ted Holt via the IT Jungle Contact page. RELATED STORY
|