Clicky

BCD Quadrant Software SoftBase NetLert

Press Room

Use AJAX for Bright and Shiny Web Apps, Part II

Roll up your sleeves and start coding!

by Duncan Kenzie
Published: January 2006

In my previous article, I explained how AJAX is transforming Web applications by providing a much richer and more responsive user experience. We looked at how Google and other major players are effectively using AJAX to provide functionality and ease-of-use not previously found in Web applications.

In this article, I'll help you tap into the power of AJAX by providing you with the code necessary to create the essential communications link between client (browser) and server (iSeries, etc.) that is the heart of any AJAX application.

Implement AJAX Today!

Once you have written the initial code to use an AJAX object, AJAX is very simple to implement. As I stated in the last article, since it requires only changes to the way you write client-side code, you can easily include AJAX in iSeries-based Web applications (CGIs or Java-based). In addition, all the browser infrastructure needed to implement AJAX is already available in just about every modern browser. Here's what I'll do in this article in order to help you implement AJAX right away:

  • Explain the core AJAX object
  • Walk through code for using it
  • Show you how to wrap that code in a self-contained "black box"
  • Show sample uses of that black box

These steps assume some degree of familiarity with writing server-side code for Web applications using any Web server language, such as CGIDEV2 (RPG CGI), PHP, ASP, JSP, or Java servlets. My server-side code is written using WebSmart, which runs on the AS/400 or iSeries as RPG CGI code. By way of acknowledgment, some of the code in this article is derived from code at Apple's Developer's site. I've improved on it by making it more generic so that it's easy to use in several different ways on any given page.>

The Core AJAX Object

The core AJAX object is a JavaScript object called XMLHttpRequest. So, in order to implement AJAX, you'll need some JavaScript. Don't worry if you don't know how to code JavaScript; the basic syntax is fairly straightforward. (For more information about what JavaScript is, see the sidebar at the end of this article.) And I've provided links to a downloadable zip file that contains complete code you can plug in to your applications, along with a sample implementation Web page.

Figure 1 shows an example conversation using an AJAX object embedded in a Web page to provide the kind of auto-complete feature used by Google's Gmail. Usually, browser content is sent from the server to the client in entire pages. In the AJAX model, it's sent as content fragments that you can use to update portions of a page without reloading the entire thing.

Ajax interaction flow chart here

Figure 1: Here's an example of a conversation.

Internet Explorer (IE) browsers implement the XMLHttpRequest object differently than Mozilla-based browsers (such as Firefox). IE implements it as a native ActiveX (one that is automatically included in the browser code base), while Firefox implements it as a JavaScript native object. The differences are purely cosmetic, but any robust script that uses AJAX needs to take the different browser implementations into account. Fortunately, this is fairly easy. You can check for the existence of the object by using a browser-feature detection technique. Note that this technique is now much preferred over examining a variable that describes the browser, as it is much more reliable and not subject to changes in browser names or release levels. Here's the initial JavaScript code:

 

var _ms_AJAX_Request_ActiveX = "";

//  global variable: holds type

//of ActiveX toinstantiate

// code for Mozilla, etc.

if (window.XMLHttpRequest) {

    var xmlhttp=new XMLHttpRequest();

    }



 // code for IE

else if (window.ActiveXObject) {

   // Instantiate the latest MS ActiveX Objects

   if (_ms_AJAX_Request_ActiveX){

     xmlhttp =

     new ActiveXObject(_ms_AJAX_Request_ActiveX);

     }

     else {

       // loops through the

       //various versions of XMLHTTP to

       //ensure we're using the latest	

       var versions = ["Msxml2.XMLHTTP.7.0",

                      "Msxml2.XMLHTTP.6.0",

                      "Msxml2.XMLHTTP.5.0",

                      "Msxml2.XMLHTTP.4.0",

                      "MSXML2.XMLHTTP.3.0",

                      "MSXML2.XMLHTTP",

                      "Microsoft.XMLHTTP"];

       for(var i = 0; i < versions.length ; i++) {	

          try {

          // Try to create the object. 

          //If it doesn't work,

          // we'll try again

          // if it does work, we'll save a

          //reference to the proper one to

          //speed up future instantiations

          xmlhttp  = new ActiveXObject(versions[i]);

          if (xmlhttp) {

             _ms_AJAX_Request_ActiveX = versions[i];

             break;

          }

       }

       catch (objException) {

       // trap -  try next one

       }

     }

 }

Explanation of Code

We will eventually embed this script in a function that is easily called. Here's what it does: First, it checks for support for the XMLHttpRequest native object. If this succeeds (returns true), then the browser is Mozilla-based, and we create a new instance of the object, named xmlhttp. If that check fails, it checks for an IE ActiveX version. (Microsoft has deployed different versions over time, which is why the code loops through an array to find the correct one.) Once the correct version is found, we instantiate a new object instance with the same name, xmlhttp.

So in either case, Mozilla or IE, we create an object called xmlhttp. This object is the core AJAX component. It has several properties and methods, all well-documented at the aforementioned Apple Web page and at Microsoft's developer site. Fortunately, most of the important methods and properties are shared by both the Mozilla and IE implementations, so we don't have to worry about writing a lot of branched code to handle different browsers.

Walkthrough of Code Fragments for Using the AJAX Object

OK, now we have an instance of our core AJAX object, xmlhttp. The next piece of code is a complete function that includes the above fragment and makes an AJAX call to the server:

function AJAX_Update(url, obj, func)

2  if (!url) return false;

     // Don't run if missing the url parm.

     // ... earlier code to

     //instantiate xmlhttp goes here

     if (!xmlhttp) return false;

3    if (func)

      xmlhttp.onreadystatechange = function(){

4        if (xmlhttp.readyState != 4) return;

5      if (xmlhttp.status == 200)

           func(obj, xmlhttp.responseText);

       else

           alert("An error occurred" + http.status);

    };

6   else{

       xmlhttp.onreadystatechange = function() {

     return; 

    }

7  xmlhttp.open('GET', url, true);

      xmlhttp.send(null);

        return false;}

         

Explanation of Code

Point 1

The entire AJAX interface is encapsulated in a function called AJAX_Update, which uses three mandatory parameters:

  • url—The string that contains the URL of the server-side program to call. For example,
    custsearch.pgm?task=search&searchval=FRED
  • obj—The object reference to an HTML element on the page. This is the section of the page that will be updated by the AJAX request. For example, if we have an HTML element with an ID of "ajaxresponse" (like this <div id="ajaxresponse">Response from AJAX call goes in here</div>), then the value of obj would be "ajaxresponse".
  • func—The name of a JavaScript function in our page that will update the page contents with the AJAX response. For example,
  • AJAX_Update(myurl, mydiv, Receive_AJAX_Response);
    would call this function:
    function Receive_AJAX_Response
    
        (mydiv, response ) {
    
        document.getElementById(mydiv).innerHTML =
    
        response;
    
        }

This last parameter might be a little strange to RPG programmers. JavaScript allows us to reference a function through the contents of a variable, rather than as a hard-coded value. This means we can invoke our function (AJAX_Update) any number of times in the page and have it call different functions to update page content. This is like using procedure pointers in RPG. We'll see how this is used in the description of point 5 in the code.

Point 2

Since the URL parameter is mandatory, its absence will cause the function to exit gracefully. After point 2, we insert our code to instantiate the AJAX (xmlhttp) object described earlier.

Point 3

The third parameter is the function that handles the response. If present, we assign an "anonymous" function (an ad hoc one, with no name) to an event handler for the AJAX object for when the "ready" state of the object changes. The ready state will change as a result of a server call , which actually takes place in point 7.

Point 4

This point assigns an event handler to the AJAX object's ready state. The event indicating that the state is changed is fired when the code has done a server call and gotten a response from the server (initiated in step 7). If the new state is not 4, we exit (4 is a valid ready state; any other is not).

Point 5

If the returned status from the server is 200, then we have a valid response from the server and we can continue. If not, we send an alert box notifying the user that an error occurred. In production code, we might want to handle this more gracefully. Possible return codes are ones such as the infamous "404 — page not found." This could happen if the URL you attempt to reference is incorrect, for example. These are standard responses according to the HTTP protocol. The key line of code at this point is

func(obj, xmlhttp.responseText);

This invokes the function we passed as the third parameter in point 1 in this case: Receive_AJAX_Response. Note that it requires two parameters: the AJAX response data and the ID of some HTML element on the page that is to be updated. In our example, the code looks like this:

function Receive_AJAX_Response(mydiv, response )

{

 document.getElementById(mydiv).innerHTML = 

                                response; 

}

This function takes the contents of the variable response (the server's response from the AJAX call) and updates the inner contents of the HTML element identified by variable mydiv. So, if mydiv = ajaxresponse, then this div's inner HTML contents will get replaced with whatever HTML or text was returned by the server:

<div id="ajaxresponse">

 Response from AJAX call goes in here

</div>

Point 6

This is the graceful exit if no parameter for the receiving function was passed.

Point 7

The "open" method of the AJAX object prepares for the actual call to the server, while the "send" method actually does it. You can think of this as being the invisible squirrel in your browser who is clicking on a hidden link or form button behind the scenes.

The first parameter of the open method determines whether to use 'GET' or 'PUT' to make the request. This equates to the ACTION keyword on the HTML <FORM> tag.

The second parameter is the URL we want to go to. As you'll see in the implementation code, it will typically be a call to a server program such as a CGI or a servlet. Here's an example of constructing a URL that calls a WebSmart program called findcust:

var myurl += "findcust.pgm?task=

              ajaxresponse&searchval=" + 

              encode(field.value); 

The third parameter (true) tells the AJAX object to operate asynchronously with respect to other page activity. This is the first A in the acronym AJAX (asynchronous), and it's very important. It allows the browser to remain unlocked so the user can continue to interact with it while the server communicates with the AJAX object. Depending on your implementation, several AJAX calls could be queued up at one time while the user is still typing. For example, the Google approach does a server call on every user key stroke. By using the asynchronous setting, you free up the browser while the background work of sending and receiving responses is queued and executed. Most implementations of AJAX use an asynchronous design (otherwise, they would be SJAX, I suppose!).

Using the Script in Your Pages

I've encapsulated the above script in an external JavaScript file so that AJAX_Update can be treated as a "black box." You can easily reference it in your pages like this:

<head>

     <script src="/mypath/ajax_update.js">

     </script>

</head>

(Here, "mypath" is your own path to the script.)

This simple Customer lookup example uses the external file ajax_update.js. You can click on the link and then view the source in your browser to see all the script.

These are the important code fragments to implement this:

1. Attach event handler for when the user leaves the Customer number input field:

<input type="text" id="cstno"

       name="cstno" size=7

       maxlength=7

       onBlur="Send_AJAX_Request(this);">

2. Event handler code for customer number input field:

function Send_AJAX_Request(target) {

      // pass the query the user has typed.

      // Also, pass the id for a div to update,

      // and the function to

      //call to update this div.

     var myurl =

         "ajaxcst4.pgm?task=ajaxresp&cstno="+

          encodeURIComponent(target.value);

     mydiv = document.getElementById("result_div");  



     // Fire request for data and populate div:

     AJAX_Update(myurl, mydiv,

     Receive_AJAX_Response); }

3. Function to update the page contents ( the result div) :

function Receive_AJAX_Response(mydiv, response ){

     // display the div at the proper position 

     mydiv.innerHTML = response; }

There are lots of variations on when you might want to invoke the AJAX object. For example, in Google mail, it gets invoked for every keystroke, not just when the user exits a field. You can trap for a keystroke event using the onKeyUp event handler. A detailed explanation of that is beyond the scope of this article, but you can review the source in the examples from the last article to see how it's done.

Ready, Set, Go!

Now you have all the tools to start implementing AJAX in your Web applications. Be creative and judicious in your use of AJAX and you can bring a whole new richness to your users' Web experiences, providing Windows-like functionality in a browser.

Sidebar: What JavaScript Really Is

JavaScript is not Java. Although there are some syntactical similarities and both have "Java" in the name, that's where the similarity ends. JavaScript is a scripting (interpretive) language that runs inside your browser. You can think of it as similar to early incarnations of BASIC or Visual Basic in that a run-time interpreter parses and executes the script. Usually, JavaScript is coded using typical procedural language coding techniques, but you can also write it using object-oriented programming concepts and constructs. All modern browsers support JavaScript, and the majority of users allow JavaScript to run in their pages. JavaScript execution can be turned off via browser security settings, but only really paranoid users will do that. Since you are likely to be writing business applications for the Web, you can probably get away with imposing a corporate standard that the user's browser must have JavaScript support turned on.

Duncan Kenzie is President and CTO of BCD Technical Support, the development and support group for WebSmart a popular iSeries Web development tool, and Nexus, a portal product specifically designed for iSeries, i5, and AS/400 servers. Duncan has 29 years of experience on the midrange systems platform creating software for both green-screen and native Web environments.