Welcome!

AJAX & REA Authors: John Funnell, Bob Little, Kevin Hoffman, Maureen O'Gara, Onkar Singh

Related Topics: AJAX & REA

AJAX & REA: Article

Intelligent Web Applications with AJAX

A peek into modern technologies for browser-based applications

Let's look at the function handleResponse(). Since it can be invoked at different states of the request processing, the function ignores all cases except the one when the request processing is complete. This corresponds to the request.readyState property equal to 4 ("Completed"). At this point the function reads the server's response text. Contrary to what its name may suggest, neither the input nor the output of XmlHttpRequest has to be restrained to XML. In particular, our resolveZip.jsp (see Listing 1) returns plain text. If the return value is "unknown" the function assumes that the zip code was invalid and changes the border color of the lookup field (zip) to red. Otherwise, the return value is used to populate the fill field (state or city), and zip's border is assigned a default color.

XMLHttpRequest - the Transport Object
Let's return to our cross-browser implementation of XMLHTTPRequest. The last listing contains an HttpRequest() function that's upward-compatible with IE5.0 and Mozilla 1.8/FireFox. For simplicity's sake, we just try to create a Microsoft XMLHTTPRequest object - and if that fails we assume it's Firefox/Mozilla.

At the heart of this function is the XMLHTTPRequest - a native browser object, which facilitates anything that involves HTTP protocol in commu-nicating with the server. It allows specifying any HTTP verbs, headers, and payload and works in either asynchronous or synchronous mode. No downloads or plugins are required, although in the case of IE, XMLHTTPRequest is an ActiveX integrated inside the browser. Accordingly, the "Run ActiveX Control and Plugins" default IE permission should be in place to use it.

Most important, XMLHTTPRequest allows an RPC-style programmatic query to the server without any page refresh.

It does it in a predictable, controlled way, offering complete access to all details of the HTTP protocol, including the headers and any custom formatting of the data. In future articles, we'll show you industrial protocols that you can run on top of this transport including Web Services and XML-RPC that greatly simplify developing and maintaining large-scale applications.

The Server-Side Logic
Finally, the server-side resolveZip.jsp is invoked from the function ask() as shown in Listing 1. The resolveZip.jsp is called in two separate scenarios differentiated by the current length of the zip code (see the zipChanged() function.) The value of the request parameter lookupType is either state or city. For simplicity's sake, we'll assume that two files, state.properties and city.properties, are located in the root directory of the c: drive of the server. The resolveZip.jsp logic is confined to returning the lookup value with the appropriate pre-loaded file - once in each case of course.

Our AJAX-enabled page is ready. The complete working example is available at: www.ajaxmaker.com:8080/blog/zipsearch.htm.

Remote Scripting - An Alternative Approach
Some older AJAX implementations are based on so-called remote scripting. The idea is that the user's actions result in querying the server via IFRAME, and the server responds with the JavaScript, which is immediately executed as soon as it reaches the client. This is a big difference compared to XMLHttpRequest approach, where the server responds with the data and the client interprets the data. The advantage is that this solution supports older browsers.

The HTML portion of the IFRAME-based example (see Listing 2) is similar to the one we've used in the XMLHTTPRequest scenario, but this time we'll introduce an extra IFRAME element - controller:

Zip:<input id="zipcode" type="text" maxlength="5" onKeyUp="zipChanged()" style="width:60" size="20"/>
City: <input id="city" disabled maxlength="32" style="width:160" size="20"/>
State:<input id="state" disabled maxlength="2" style="width:30" size="20"/>
<iframe id="controller" style="visibility:hidden;width:0;height:0"></iframe>

We keep calling zipChanged() per every key stroke, but this time the function ask(), called from zipChanged() (see Listing 3), sets the IFRAME's src property, instead of invoking an XMLHTTPRequest:

function ask(url, fieldToFill, lookupField)
{
    var controller = document.getElementById("controller");
    controller.src = url+"&field="+fieldToFill.id+"&zip="+lookupField.id;
}

The server-side logic is presented by a sketchy resolveZip.jsp (see Listing 4). It's different from its XMLHTTPRequest counterpart in that it returns JavaScript statements, which set the global values of the variables field lookup and city and the call function response() from the global window's execution context as soon as it gets to the browser.

The function response() is a modified version of the handleResponse() which is absolved from dealing with uncompleted requests (see Listing 2.)

The Fine Print
For simplicity's sake, we've "overlooked" some important issues in our sample code:

1.  The fact that the instances of the XMLHTTPRequest object and callback invocations haven't been destroyed after being used, which causes memory leaks after every call. Properly written code should destroy or reuse such instances in the object pool. Object management techniques common to the server software have to be used for the client

2.  In quite a few places the errors weren't handled properly. For example, the call to request.open() in the method ask() can throw an exception that has to be caught and processed even though JavaScript exceptions don't have to be checked. The handleResponse() function is another example. It has to check headers and responseText for possible server-side and communication errors. In case of an error, it has to try to recover and/or report an error. Properly developed AJAX applications eliminate loosing data on "submissions" due to disconnects and other low-level communication problems via a robust, self-recovering framework.

3.  Current server-side frameworks provide quite a few functions that have to be reconciled with a refresh-free approach. For example, let's consider a custom server-side authentication with a timeout. In that case we'd have to intercept security system response to the XMLHTTPRequest calls, bring up the login screen, and then re-issue the request after the user was authenticated.

All these problems are typical of any application code working with low-level APIs and all of them can be resolved. The good news is that the technologies needed to resolve these issues are quite familiar to most Java developers like Web Services, custom tags, and XML/XSLT. The only difference is that nowadays these technologies come to the rescue on the client in the form of:

  • Web Services using SOAP/REST/RPC for a simple communication standard
  • Client-side custom tags for packaging rich client-side controls with integrated AJAX functionality
  • XML- and XSLT-based data manipulation
Summary
The AJAX approach offers a rich Internet experience on a par with that of desktop applications. AJAX features have to be applied selectively: you definitely don't want your credit card charged by the background process while you're still shopping. Is AJAX momentum sustainable? We certainly hope so. We've been developing AJAX applications for the last sive years and can attest that it's sound and very effective. However, it requires that a developer be exposed to a much wider set of technologies than the ones used in the traditional "click-refresh" Web applications.

Part 2
The publicity that AJAX grabbed over the last half a year is based on closing the gap between the Web applications and the desktop applications, combining the "reach" and "rich." At the same time, the gap between the technological level of AJAX and what corporate developers expect in their modern arsenal is really astonishing. After all, AJAX is neither a tool nor a platform. There is no AJAX standards committee or community process in place. While software vendors are crafting proprietary development platforms on top of AJAX (which pretty much means "from scratch"), early adopters of AJAX are left on their own.

In the previous section, we touched on the foundation of AJAX - the ability to establish script-to-server communication. This is what makes HTML pages dynamic and responsive. Does it mean we are ready to kick-off our own version of Yahoo mail? No, we are not. Here is why: AJAX is a mixed blessing. On one hand it enables us to create rich, desktop-class applications on the Web. On the other, if we compare "page-flipping" Web applications with the client/server or Swing ones, the development practices are not quite the same. What about management expectations? We'll need to get used to the fact that it takes time to build a rich UI. The more flexibility with more permutations the user is allowed - the more time it takes.

The answer, of course, is component libraries, frameworks, and industrial-strength tools. Leaving tools aside, this article concentrates on what is available for AJAX enthusiasts today. Addressing a need to build reusable business components, it focuses on the "hidden" object-oriented power of JavaScript. Also, by addressing a need to build custom-rich UI components, it illustrates a convenient way to encapsulate presentation logic in custom client-side HTML tags.

AJAX Language: Object-Oriented JavaScript
By definition, JavaScript is the language of classic AJAX. Unlike Java, JavaScript does not enforce the OO style of coding. That said, it's surprising how often it's overlooked that Java-Script fully supports all the major attributes of an OO language: inheritance, polymorphism, and encapsulation. Douglas Crockford even named Java Script "The World's Most Misunderstood Programming Language." Let's review the object-oriented side of JavaScript.

Data Types
In Java, a class defines a combination of data and its associated behaviors. While JavaScript reserves the class keyword, it does not support the same semantic as in conventional OOP languages.

It may sound strange but in JavaScript, functions are used as object definitions. By defining a function in the example below you, in fact, define a simple empty class - Calculator:

function Calculator() {}

A new instance is created the same way as in Java - by using the new operator:

var myCalculator = new Calculator();

The function not only defines a class, but also acts as a constructor. The operator new does the magic, instantiating an object of class Calculator and returning an object reference in contrast to merely calling the function.

Creating an empty class is nice but not really useful in real life. We are going to fill-in the class definition using a Java-Script prototype construct. JavaScript uses prototype to serve as a template for object creation. All prototype properties and methods are copied by reference into each object of a class, so they all have the same values. You can change the value of a prototype property in one object, and the new value overrides the default, copied from the prototype, but only in that one instance. The following statement will add a new property to the prototype of the Calculator object:

Calculator.prototype._prop = 0;


More Stories By Victor Rasputnis

Dr. Victor Rasputnis is a Managing Principal of Farata Systems. He's responsible for providing architectural design, implementation management and mentoring to companies migrating to XML Internet technologies. He holds a PhD in computer science from the Moscow Institute of Robotics. You can reach him at vrasputnis@faratasystems.com

More Stories By Anatole Tartakovsky

Anatole Tartakovsky is a Managing Principal of Farata Systems. He's responsible for creation of frameworks and reusable components. Anatole authored number of books and articles on AJAX, XML, Internet and client-server technologies. He holds an MS in mathematics. You can reach him at atartakovsky@faratasystems.com

More Stories By Igor Nys

Igor Nys is a Director of Technology Solutions at EPAM Systems, Inc, a company combining IT consulting expertise with advanced onshore-offshore software development practices. Igor has been working on many different computer platforms and languages including Java, C++, PowerBuilder, Lisp, Assembler since the mid 80's. Igor is currently managing a number of large distributed projects between US and Europe. In addition Igor is the author of the award-winning freeware system-management tools, and he was closely involved in the development of XMLSP technology - one of the AJAX pioneers.

Comments (2) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Bill Watkins 11/09/06 12:18:37 PM EST

www.ajaxmaker.com:8080/blog/zipsearch.htm.
volumn1 issue 1 The above link is non functional to the public. Bad form for any magazine.

Overall nice first effort though.

Dennis 10/17/06 08:39:39 AM EDT

The text and the code are not consistent. This makes it tough to follow the concepts being presented in the article. For example: "Let's look at the function handleResponse()..." There is no function "handleResponse()" in the code. The function ask() is explained before its presented in the code examples. The anonymous function "handleHTTPRequest" is presented in the text as "function (){ handleHttpResponse(http, fieldToFill, lookupField)}" and in the code as "function handleHttpResponse(http, fieldToFill, lookupField)".
Educational articles should be consistent to maximize their value.