Consisting of HTML, JavaScript™ technology, DHTML, and the DOM, Ajax is a brilliant way to transform cumbersome Web interfaces into interactive Ajax applications. This article, written by an Ajax expert, demonstrates how these technologies work together—from a general overview to a detailed discussion—to make efficient Web development a reality. He also demystifies core Ajax concepts, including the XMLHttpRequest object.
Five years ago, if you didn't know XML, you were an ugly duckling that no one took seriously. Eighteen months ago, Ruby became the center of attention, and programmers who didn't know Ruby could only sit on the bench. Today, if you want to keep up with the latest technology fads, your destination is Ajax.
But Ajax is more than just a fad, it's a powerful way to build websites that isn't as difficult as learning a whole new language.
But before we get into the details of what Ajax is, let's take a few minutes to understand what Ajax does. Currently, there are two basic options when writing applications:
· Desktop applications · Web applications
The two are similar, desktop applications usually come on CD (sometimes downloadable from a website) and are fully installed on your computer superior. Desktop applications may use the Internet to download updates, but the code that runs these applications is on the desktop computer. Web applications run on a Web server somewhere—not surprisingly, such applications are accessed through a Web browser.
However, more important than where the code that runs these applications is placed is how the applications function and interact with them. Desktop applications are generally fast (run right on your computer without waiting for an Internet connection), have a beautiful user interface (usually operating system dependent), and are remarkably dynamic. You can click, select, type, open menus and submenus, navigate around, and basically never wait.
Web applications, on the other hand, are the latest trend, providing services that are not possible on the desktop (such as Amazon.com and eBay). However, with the power of the Web comes the need to wait, wait for the server to respond, wait for the screen to refresh, wait for the request to return and generate a new page.
Obviously this is an oversimplification, but the basic concept is this. As you may have guessed, Ajax attempts to bridge the functionality and interactivity of desktop applications with the ever-evolving Web applications. You can use dynamic user interfaces and beautiful controls like those found in desktop applications, but in a Web application.
What are you waiting for? Let's take a look at how Ajax can transform clumsy Web interfaces into responsive Ajax applications.
Old technology, new tricks
When it comes to Ajax, it actually involves a variety of technologies, and using it flexibly requires a deep understanding of these different technologies (the first few articles in this series will discuss each of these technologies separately). The good news is that you're probably already very familiar with most of these technologies, and even better is that they're easy to learn and not as difficult as a full programming language like Java or Ruby.
The following are the basic technologies used in Ajax applications:
·HTML is used to build Web forms and determine the fields used by other parts of the application.
· JavaScript code is the core code that runs Ajax applications and helps improve communication with server applications.
·DHTML or Dynamic HTML for dynamically updating forms. We'll use divs, spans, and other dynamic HTML elements to mark up HTML.
·The Document Object Model DOM is used to process (via JavaScript code) the structure of HTML and (in some cases) the XML returned by the server.
Definition of Ajax
By the way, Ajax is the abbreviation of Asynchronous JavaScript and XML (and DHTML, etc.). This phrase was coined by Jesse James Garrett of Adaptive Path (see Resources), and as Jesse explains, it's not an acronym.
Let’s further analyze the responsibilities of these technologies. I'll discuss these technologies in depth in future articles, but for now just familiarize yourself with the components and technologies. The more familiar you are with these codes, the easier it will be to move from a scattered understanding of these technologies to a true grasp of these technologies (which also truly opens the door to Web application development).
XMLHttpRequest Object
The one object to understand may also be the most unfamiliar to you, the XMLHttpRequest. This is a JavaScript object, and creating it is simple, as shown in Listing 1.
Listing 1. Creating a new XMLHttpRequest object
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>
We will discuss this object further in the next article, but for now know that this is the object that handles all server communication. Before you continue reading, stop and think about this: JavaScript technology is the one talking to the server through the XMLHttpRequest object. This is not ordinary application flow, and this is where the power of Ajax comes from.
In a typical Web application, the user fills out the form fields and clicks the Submit button. The entire form is then sent to the server, which forwards it to a script that handles the form (usually PHP or Java, maybe a CGI process or something similar), and then sends back a brand new page when the script is complete. The page might be HTML with a new form already populated with some data, it might be a confirmation page, or it might be a page with some options selected based on the data entered in the original form. Of course, the user must wait while the script or program on the server processes and returns the new form. The screen goes blank and waits until data is returned from the server before redrawing. This is why interactivity is poor, the user doesn't get immediate feedback, so it feels different than a desktop application.
Ajax basically puts JavaScript technology and the XMLHttpRequest object between the Web form and the server. When the user fills out the form, the data is sent to some JavaScript code instead of directly to the server. Instead, the JavaScript code captures the form data and sends a request to the server. At the same time, the form on the user's screen will not flicker, disappear, or delay. In other words, the JavaScript code sends the request behind the scenes without the user even knowing that the request is being made. Even better, the request is sent asynchronously, which means the JavaScript code (and the user) don't have to wait for a response from the server. So the user can continue to enter data, scroll, and use the application.
The server then returns the data to JavaScript code (still in the Web form), which decides what to do with the data. It updates form data quickly, giving the impression that the application is completed instantly, without the form being submitted or refreshed and the user getting new data. The JavaScript code can even perform some calculation on the received data and send another request, all without user intervention! This is the power of XMLHttpRequest. It can interact with the server on its own as needed, and the user can even be completely unaware of what's going on behind the scenes. The result is a dynamic, responsive, highly interactive experience similar to a desktop application, but with all the power of the Internet behind it.
Afteradding some JavaScript
to get the handle of XMLHttpRequest, the other JavaScript code is very simple. In fact, we will use JavaScript code to accomplish very basic tasks:
· Get form data: JavaScript code can easily extract data from an HTML form and send it to the server.
·Modify data on the form: Updating the form is also easy, from setting field values to quickly replacing images.
·Parse HTML and XML: Use JavaScript code to manipulate the DOM (see next section) and process the structure of the XML data returned by the HTML form server.
For the first two points, you need to be very familiar with the getElementById() method, as shown in Listing 2.
Listing 2. Capturing and setting field values with JavaScript code
// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;
// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];
There is nothing special to note here, it's great! You should realize that there's nothing terribly complicated here. Once you've mastered XMLHttpRequest, the rest of your Ajax application is simple JavaScript code, as shown in Listing 2, mixed with a small amount of HTML. At the same time, we also need to use a little bit of DOM, so let's take a look.
Ending with DOM
Finally there is DOM, the Document Object Model. The DOM may be a bit intimidating to some readers. HTML designers rarely use it, and even JavaScript programmers rarely use it unless they want to complete a high-end programming task. Complex Java and C/C++ programs make heavy use of the DOM, which may be why the DOM is considered difficult to learn.
Fortunately, working with the DOM in JavaScript technology is easy and very intuitive. Now, conventionally you should probably explain how to use the DOM, or at least give some example code, but doing so might also mislead you. Even if you ignore the DOM, you can still delve into Ajax, and that's the approach I'm going to take. We'll revisit the DOM in a future article, but for now suffice it to know that you might need it. We'll delve deeper into the DOM when we need to pass XML between JavaScript code and the server and change HTML forms. You can do some interesting work without it, so put the DOM aside for now.
Obtaining the Request object
With the above basic knowledge, let's take a look at some specific examples. XMLHttpRequest is at the heart of Ajax applications and may be unfamiliar to many readers, so let's start there. As you can see from Listing 1, creating and using this object is very simple, isn't it? Wait.
Remember those nasty browser wars from a few years ago? Nothing gives the same results across different browsers. Believe it or not, these wars are still going on, albeit on a smaller scale. But strangely, XMLHttpRequest became one of the casualties of this war. Therefore obtaining the XMLHttpRequest object may require a different approach. I'll explain it in detail below.
Using the Microsoft browser
Microsoft browser Internet Explorer uses an MSXML parser to process XML (you can learn more about MSXML in Resources). Therefore, if you write an Ajax application that interacts with Internet Explorer, you must create objects in a special way.
But it's not that simple. There are actually two different versions of MSXML depending on the version of the JavaScript technology installed in Internet Explorer, so you must write separate code for each case. See Listing 3, which contains code that creates an XMLHttpRequest on a Microsoft browser.
Listing 3. Create XMLHttpRequest object on Microsoft browser
var xmlHttp = false;
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
You may not fully understand the code yet, but that's okay. By the end of this series of articles, you will have a deeper understanding of JavaScript programming, error handling, conditional compilation, and more. Now just remember the two lines of code:
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
and
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.
These two lines of code basically try to create an object using one version of MSXML, and if that fails, create the object using another version. Not bad, right? If neither succeeds, the xmlHttp variable is set to false, telling your code that there is a problem. If this occurs, it may be because a non-Microsoft browser is installed that requires different code.
Handling Mozilla and non-Microsoft browsers
If you choose a browser other than Internet Explorer, or if you write code for a non-Microsoft browser, you will need to use different code. It's actually a simple line of code shown in Listing 1:
var xmlHttp = new XMLHttpRequest object;.
This much simpler line of code creates an XMLHttpRequest object in Mozilla, Firefox, Safari, Opera, and basically any non-Microsoft browser that supports Ajax in any form or fashion.
The keyto combining this
is to support all browsers. Who wants to write an application that only works with Internet Explorer or non-Microsoft browsers? Or worse, writing an application twice? Of course not! Therefore the code needs to support both Internet Explorer and non-Microsoft browsers. Listing 4 shows such code.
Listing 4. Creating an XMLHttpRequest object in a way that supports multiple browsers
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
@end @*/
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}
For now, ignore the strange symbols commented out, such as @cc_on, which are special JavaScript compiler commands that will be discussed in detail in the next article on XMLHttpRequest. The core of this code is divided into three steps:
1. Create a variable xmlHttp to reference the XMLHttpRequest object to be created.
2. Try to create the object in Microsoft browser:
1) Try to create it using Msxml2.XMLHTTP object.
2) If it fails, try the Microsoft.XMLHTTP object again.
2. If xmlHttp is still not created, create the object in a non-Microsoft way.
Finally, xmlHttp should reference a valid XMLHttpRequest object, no matter what browser it is running.
A little note on security.
How about security? Browsers now allow users to increase their security level, turn off JavaScript technology, and disable any option in the browser. In this case the code won't work anyway. At this point it is necessary to deal with the problem appropriately, which requires a separate article for later (this series is long enough, right? Don't worry, you may get it before you finish reading). Now let's write a piece of code that's robust but not perfect, which is good for mastering Ajax. We will discuss this in more detail later.
Request/Response in the Ajax World
Now that we've introduced Ajax, we have a basic understanding of the XMLHttpRequest object and how to create it. If you've read carefully, you probably already know that it's JavaScript technology that deals with Web applications on the server, rather than HTML forms that are submitted directly to that application.
What's missing? Exactly how to use XMLHttpRequest. Because this code is so important that every Ajax application you write will use it in some form, let's start by looking at what the basic request/response model of Ajax looks like.
Making the request
Now that you have a brand new XMLHttpRequest object, let's let it do some work. First, you need a JavaScript method that the Web page can call (for example, when the user enters text or selects an item from a menu). Next is the process that is basically the same in all Ajax applications:
1. Obtain the required data from the Web form.
2. Create the URL to be connected.
3. Open a connection to the server.
4. Set the function to be run by the server after completion.
5. Send a request.
The sample Ajax methods in Listing 5 are organized in this order:
Listing 5. Making an Ajax request
function callServer() {
// Get the city and state from the web form
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
// Only go on if there are values for both fields
if ((city == null) || (city == "")) return;
if ((state == null) || (state == "")) return;
// Build the URL to connect to
var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);
// Open a connection to the server
xmlHttp.open("GET", url, true);
// Setup a function for the server to run when it's done
xmlHttp.onreadystatechange = updatePage;
// Send the request
xmlHttp.send(null);
}
The meaning of most of the codes is very clear. The code at the beginning uses basic JavaScript code to get the values of several form fields. Then set a PHP script as the target of the link. Note the way the script URL is specified, the city and state (from the form) are appended to the URL using simple GET parameters.
Then a connection is opened, which is the first time you see XMLHttpRequest being used. The connection method (GET) and the URL to connect to are specified. The last parameter, if set to true, will request an asynchronous connection (this is the origin of Ajax). If false is used, the code will wait for a response from the server after making the request. If set to true, users can still use the form (and even call other JavaScript methods) while the server handles requests in the background.
The onreadystatechange attribute of xmlHttp (remember, this is an XMLHttpRequest object instance) tells the server what to do after it has finished running (which may take five minutes or five hours). Because the code is not waiting for the server, it must let the server know what to do so that you can respond. In this example, if the server has finished processing the request, a special method called updatePage() will be triggered.
Finally, send() is called with the value null. Because the data to be sent to the server (city and state) has been added to the request URL, no data needs to be sent in the request. This way the request is made and the server works as per your request.
If you don't find anything new, you should appreciate how simple and straightforward this is! Other than keeping in mind the asynchronous nature of Ajax, this is all pretty simple. Be grateful that Ajax allows you to focus on writing beautiful applications and interfaces instead of worrying about complex HTTP request/response code.
The code in Listing 5 illustrates the ease of use of Ajax. The data is simple text and can be used as part of the request URL. Send requests with GET instead of the more complex POST. There is no XML and no content headers to add, and no data to send in the request body; in other words, this is Ajax utopia.
Don’t worry, things will get more complicated as this series of articles unfolds. You'll see how to send a POST request, how to set the request headers and content type, how to encode XML in the message, how to increase the security of the request, and there's a lot more you can do! Don't worry about those difficulties for now, just master the basic things, and soon we will build a complete set of Ajax tool libraries.
Handling the Response
Now comes the server's response. Just two things to know for now:
· Do nothing until the value of the xmlHttp.readyState property is equal to 4.
·The server will populate the xmlHttp.responseText property with the response.
The first of these, the ready state, will be discussed in detail in the next article, and you'll learn more about the stages of an HTTP request than you probably thought. For now it is enough to check for a specific value (4) (there will be more values to cover in the next article). Second point, use the xmlHttp.responseText property to get the server's response, it's very simple. The example method in Listing 6 can be called by the server based on the data sent in Listing 5.
Listing 6. Handling server response
function updatePage() {
if (xmlHttp.readyState == 4) {
var response = xmlHttp.responseText;
document.getElementById("zipCode").value = response;
}
}
The codes are also neither difficult nor complex. It waits for the server to call, and if it is ready, sets the value of another form field using the value returned by the server (here the ZIP code of the city and state entered by the user). So suddenly the zipCode field containing the ZIP code appears without the user pressing any buttons! This is what I mentioned earlier as a desktop application. Fast response, dynamic feeling, etc., all because of a small piece of Ajax code.
Careful readers may notice that zipCode is an ordinary text field. Once the server returns the ZIP encoding, the updatePage() method sets the value of that field with the city/state ZIP encoding, which the user can override. This is done for two reasons: to keep the example simple and to illustrate that sometimes you may want the user to be able to modify the data returned by the server. Keep these two things in mind, they are important for good user interface design.
What else is there
to connect to a web form
?There actually isn’t much left. One JavaScript method captures the information the user enters into the form and sends it to the server, and the other JavaScript method listens and processes the response and sets the field's value when the response comes back. All of this actually relies on calling the first JavaScript method, which kicks off the entire process. The most obvious solution is to add a button to the HTML form, but that's 2001, don't you think? Let's use JavaScript technology like Listing 7.
Listing 7. Starting an Ajax process
<form>
<p>City: <input type="text" name="city" id="city" size="25"
onChange="callServer();" /></p>
<p>State: <input type="text" name="state" id="state" size="25"
onChange="callServer();" /></p>
<p>Zip Code: <input type="text" name="zipCode" id="city" size="5" /></p>
</form>
If this feels like a fairly common piece of code, you're right, it is! When the user enters a new value in the city or state field, the callServer() method is triggered and Ajax starts running. Do you understand a little bit what's going on? Well, that’s it!
Conclusion
Now you are probably ready to start writing your first Ajax application, and at least want to read the articles in the resources carefully, right? But you can start with a basic idea of how these applications work and a basic understanding of the XMLHttpRequest object. In the next installment, you'll master this object and learn how to handle communication between JavaScript and the server, how to use HTML forms, and how to obtain a DOM handle.
Now take a moment to consider how powerful Ajax applications can be. Imagine a Web form that responded instantly when you clicked a button, entered a field, selected an option from a combo box, or dragged the mouse across the screen. Think about what async actually means, think about JavaScript code running and not waiting for the server to respond to its request. What kind of problems will you encounter? What kind of field will it enter? Given this new approach, how should we change the form's design when programming?
If you spend a little time on these issues, you'll gain more than simply cutting/pasting some code into an application you don't understand at all. In the next installment, we'll put these concepts into practice, detailing the code needed to make the application work this way. So for now, enjoy the possibilities that Ajax has to offer.