You are on page 1of 43

Mastering Ajax, Part 1: Introduction to Ajax

Understanding Ajax, a productive approach to building Web sites, and how it works Level: Introductory Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. 06 Dec 2005 Ajax, which consists of HTML, JavaScript™ technology, DHTML, and DOM, is an outstanding approach that helps you transform clunky Web interfaces into interactive Ajax applications. The author, an Ajax expert, demonstrates how these technologies work together -- from an overview to a detailed look -- to make extremely efficient Web development an easy reality. He also unveils the central concepts of Ajax, including the XMLHttpRequest object. Five years ago, if you didn't know XML, you were the ugly duckling whom nobody talked to. Eighteen months ago, Ruby came into the limelight and programmers who didn't know what was going on with Ruby weren't welcome at the water cooler. Today, if you want to get into the latest technology rage, Ajax is where it's at. However, Ajax is far more than just a fad; it's a powerful approach to building Web sites and it's not nearly as hard to learn as an entire new language. Before I dig into what Ajax is, though, let's spend just a few moments understanding what Ajax does. When you write an application today, you have two basic choices: • Desktop applications

Web applications

These are both familiar; desktop applications usually come on a CD (or sometimes are downloaded from a Web site) and install completely on your computer. They might use the Internet to download updates, but the code that runs these applications resides on your desktop. Web applications -- and there's no surprise here -- run on a Web server somewhere and you access the application with your Web browser. More important than where the code for these applications runs, though, is how the applications behave and how you interact with them. Desktop applications are usually pretty fast (they're running on your computer; you're not waiting on an Internet connection), have great user interfaces (usually interacting with your operating system), and are incredibly dynamic. You can click, point, type, pull up menus and sub-menus, and cruise around, with almost no waiting around. On the other hand, Web applications are usually up-to-the-second current and they provide services you could never get on your desktop (think about Amazon.com and eBay). However, with the power of the Web comes waiting -- waiting for a server to respond, waiting for a screen to refresh, waiting for a request to come back and generate a new page. Obviously this is a bit of an oversimplification, but you get the basic idea. As you might already be suspecting, Ajax attempts to bridge the gap between the functionality and interactivity of a desktop application and the always-updated Web application. You can use dynamic user interfaces and fancier controls like you'd find on a desktop application, but it's available to you on a Web application. So what are you waiting for? Start looking at Ajax and how to turn your clunky Web interfaces into responsive Ajax applications.

Old technology, new tricks
Ajax defined By the way, Ajax is shorthand for Asynchronous JavaScript and XML (and DHTML, and so on). The phrase was coined by Jesse James Garrett of Adaptive Path (see the Resources section) and is, according to Jesse, not meant to be an acronym. When it comes to Ajax, the reality is that it involves a lot of technologies -- to get beyond the basics, you need to drill down into several different technologies (which is why I'll spend the first several articles in this series breaking apart each one of them). The good news is that you might already know a decent bit about many of these technologies -- better yet, most of these individual technologies are easy to learn -- certainly not as difficult as an entire programming language like Java or Ruby. Here are the basic technologies involved in Ajax applications: • HTML is used to build Web forms and identify fields for use in the rest of your application.

• • •

JavaScript code is the core code running Ajax applications and it helps facilitate communication with server applications. DHTML, or Dynamic HTML, helps you update your forms dynamically. You'll use div, span, and other dynamic HTML elements to mark up your HTML. DOM, the Document Object Model, will be used (through JavaScript code) to work with both the structure of your HTML and (in some cases) XML returned from the server.

Let's break these down and get a better idea of what each does. I'll delve into each of these more in future articles; for now focus on becoming familiar with these components and technologies. The more familiar you are with this code, the easier it will be to move from casual knowledge about these technologies to mastering each (and really blowing the doors off of your Web application development).

The XMLHttpRequest object
The first object you want to understand is probably the one that's newest to you; it's called XMLHttpRequest. This is a JavaScript object and is created as simply as shown in Listing 1. Listing 1. Create a new XMLHttpRequest object

<script language="javascript" type="text/javascript"> var xmlHttp = new XMLHttpRequest(); </script> I'll talk more about this object in the next article, but for now realize that this is the object that handles all your server communication. Before you go forward, stop and think about that -- it's the JavaScript technology through the XMLHttpRequest object that talks to the server. That's not the normal application flow and it's where Ajax gets much of its magic. In a normal Web application, users fill out form fields and click a Submit button. Then, the entire form is sent to the server, the server passes on processing to a script (usually PHP or Java or maybe a CGI process or something similar), and when the script is done, it sends back a completely new page. That page might be HTML with a new form with some data filled in or it might be a confirmation or perhaps a page with certain options selected based on data entered in the original form. Of course, while the script or program on the server is processing and returning a new form, users have to wait. Their screen will go blank and then be redrawn as data comes back from the server. This is where low interactivity comes into play -- users don't get instant feedback and they certainly don't feel like they're working on a desktop application. Ajax essentially puts JavaScript technology and the XMLHttpRequest object between your Web form and the server. When users fill out forms, that data is sent to some JavaScript code and not directly to the server. Instead, the JavaScript code grabs the form data and sends a request to the server. While this is happening, the form on the users screen doesn't flash, blink, disappear, or stall. In other words, the JavaScript code sends the request behind the scenes; the user doesn't even realize that the request is being made. Even better, the request is sent asynchronously, which means that your JavaScript code (and the user) doesn't wait around on the server to respond. So users can continue entering data, scrolling around, and using the application. Then, the server sends data back to your JavaScript code (still standing in for the Web form) which decides what to do with that data. It can update form fields on the fly, giving that immediate feeling to your application -- users are getting new data without their form being submitted or refreshed. The JavaScript code could even get the data, perform some calculations, and send another request, all without user intervention! This is the power of XMLHttpRequest. It can talk back and forth with a server all it wants, without the user ever knowing about what's really going on. The result is a dynamic, responsive, highly-interactive experience like a desktop application, but with all the power of the Internet behind it.

Adding in some JavaScript
Once you get a handle on XMLHttpRequest, the rest of your JavaScript code turns out to be pretty mundane. In fact, you'll use JavaScript code for just a few basic tasks: • Get form data: JavaScript code makes it simple to pull data out of your HTML form and send it to the server.

• •

Change values on the form: It's also simple to update a form, from setting field values to replacing images on the fly. Parse HTML and XML: You'll use JavaScript code to manipulate the DOM (see the next section) and to work with the structure of your HTML form and any XML data that the server returns.

For those first two items, you want to be very familiar with the getElementById() method as shown in Listing 2. Listing 2. Grab and set 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's nothing particularly remarkable here and that's good! You should start to realize that there's nothing tremendously complicated about this. Once you master XMLHttpRequest, much of the rest of your Ajax application will be simple JavaScript code like that shown in Listing 2, mixed in with a bit of clever HTML. Then, every once in a while, there's a little DOM work...so let's look at that.

Finishing off with the DOM
Last but not least, there's the DOM, the Document Object Model. For some of you, hearing about the DOM is going to be a little intimidating -- it's not often used by HTML designers and is even somewhat unusual for JavaScript coders unless you're really into some high-end programming tasks. Where you will find the DOM in use a lot is in heavy-duty Java and C/C++ programs; in fact, that's probably where the DOM got a bit of its reputation for being difficult or hard to learn. Fortunately, using the DOM in JavaScript technology is easy, and is mostly intuitive. At this point, I'd normally show you how to use the DOM or at least give you a few code examples, but even that would be misleading. You see, you can get pretty far into Ajax without having to mess with the DOM and that's the path I'm going to show you. I'll come back to the DOM in a future article, but for now, just know that it's out there. When you start to send XML back and forth between your JavaScript code and the server and really change the HTML form, you'll dig back into DOM. For now, it's easy to get some effective Ajax going without it, so put this on the back-burner for now.

Getting a Request object
With a basic overview under your belt, you're ready to look at a few specifics. Since XMLHttpRequest is central to Ajax applications -- and probably new to many of you -- I'll start there. As you saw in Listing 1, it should be pretty easy to create this object and use it, right? Wait a minute. Remember those pesky browser wars from a few years back and how nothing worked the same across browsers? Well, believe it or not, those wars are still going on albeit on a much smaller scale. And, surprise: XMLHttpRequest is one of the victims of this war. So you'll need to do a few different things to get an XMLHttpRequest object going. I'll take your through it step by step.

Working with Microsoft browsers
Microsoft's browser, Internet Explorer, uses the MSXML parser for handling XML (you can find out more about MSXML in Resources). So when you write Ajax applications that need to work on Internet Explorer, you need to create the object in a particular way. However, it's not that easy. MSXML actually has two different versions floating around depending on the version of JavaScript technology installed in Internet Explorer, so you've got to write code that handles both cases. Look at Listing 3 for the code that you need to create an XMLHttpRequest on Microsoft browsers. Listing 3. Create an XMLHttpRequest object on Microsoft browsers var xmlHttp = false; try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { xmlHttp = false; } } All of this won't make exact sense yet, but that's OK. You'll dig into JavaScript programming, error handling, conditional compilation, and more before this series is finished. For now, you want to get two core lines into your head:
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

and
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.

In a nutshell, this code tries to create the object using one version of MSXML; if that fails, it then creates the object using the other version. Nice, huh? If neither of these work, the xmlHttp variable is set to false, to tell your code know that something hasn't worked. If that's the case, you've probably got a nonMicrosoft browser and need to use different code to do the job.

Dealing with Mozilla and non-Microsoft browsers
If Internet Explorer isn't your browser of choice or you write code for non-Microsoft browsers, then you need different code. In fact, this is the really simple line of code you saw back in Listing 1: var xmlHttp = new XMLHttpRequest object;. This much simpler line creates an XMLHttpRequest object in Mozilla, Firefox, Safari, Opera, and pretty much every other non-Microsoft browser that supports Ajax in any form or fashion.

Putting it together
The key is to support all browsers. Who wants to write an application that works just on Internet Explorer or an application that works just on non-Microsoft browsers? Worse yet, do you want to write your application twice? Of course not! So your code combines support for both Internet Explorerand nonMicrosoft browsers. Listing 4 shows the code to do just that. Listing 4. Create an XMLHttpRequest object the multi-browser way /* 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 commenting and weird tags like @cc_on; those are special JavaScript compiler commands that you'll explore in depth in my next article, which will focus exclusively on XMLHttpRequest. The core of this code breaks down into three steps:

1.
2.

Create a variable, xmlHttp, to reference the XMLHttpRequest object that you will create. Try and create the object in Microsoft browsers: o Try and create the object using the Msxml2.XMLHTTP object. o If that fails, try and create the object using the Microsoft.XMLHTTP object. If xmlHttp still isn't set up, create the object in a non-Microsoft way.

3.

At the end of this process, xmlHttp should reference a valid XMLHttpRequest object, no matter what browser your users run.

A word on security
What about security? Today's browsers offer users the ability to crank their security levels up, to turn off JavaScript technology, and disable any number of options in their browser. In these cases, your code probably won't work under any circumstances. For these situations, you'll have to handle problems gracefully -- that's at least one article in itself, one I will tackle later (it's going to be a long series, isn't it? Don't worry; you'll master all of this before you're through). For now, you're writing robust, but not perfect, code, which is great for getting a handle on Ajax. You'll come back to the finer details.

Request/Response in an Ajax world
So you now understand Ajax and have a basic idea about the XMLHttpRequest object and how to create it. If you've read closely, you even realize that it's the JavaScript technology that talks to any Web application on the server rather than your HTML form being submitted to that application directly. What's the missing piece? How to actually use XMLHttpRequest. Since this is critical code that you'll use in some form in every Ajax application you write, take a quick tour through what a basic request/response model with Ajax looks like.

Making a request
You have your shiny new XMLHttpRequest object; now take it for a spin. First, you need a JavaScript method that your Web page can call (like when a user types in text or selects an option from a menu). Then, you'll follow the same basic outline in almost all of your Ajax applications: 1. Get whatever data you need from the Web form. 2. Build the URL to connect to. 3. Open a connection to the server. 4. Set up a function for the server to run when it's done. 5. Send the request. Listing 5 is a sample of an Ajax method that does these very things, in this order: Listing 5. Make a request with Ajax 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

Once the server returns the ZIP code and the updatePage() method sets the value of that field with the city/state ZIP code.readyState == 4) { var response = xmlHttp. this code isn't so difficult or complicated. If you don't get anything else out of this.will be triggered when the server is finished processing your request. a connection is opened.this is Ajax Utopia.called updatePage() -. not much. here's the first place you see XMLHttpRequest in action again. That's the desktop application feel I talked about earlier.is easy. There's no XML or content headers to add. users can override the value.getElementById("zipCode"). how to encode XML in your message. you don't need to send anything in the request. when set to true. if you simply check for a certain value (4). Finally.responseText. } A lot of this is self-explanatory. The second item -. GET sends the request rather than the more complicated POST. You have a JavaScript method that grabs information that the user put into a form. things will work (and you'll have something to look forward to in the next article). things will become more complicated as this series progresses. It waits for the server to call it with the right ready state and then uses the value that the server returns (in this case. The first bit of the code uses basic JavaScript code to grab the values of a few form fields. document. Have no fear. By setting this to true.but the user never had to click a button!. The result is that the zipCode field suddenly appears with the ZIP code -. this is relatively simple stuff. Keep both in mind. Observant readers might notice that the zipCode field is a normal text field. // Send the request xmlHttp. For now. provides . • The server will stuff it's response into the xmlHttp.send(null). You'll appreciate how it frees you up to concentrate on cool applications and interfaces rather than complicated HTTP request/response code. and more. and you'll soon build up a whole arsenal of Ajax tools.the list is pretty long! Don't worry about the hard stuff for now. all with a little Ajax code. If you used false. no data to send in the body of the request -. requests an asynchronous connection (thus making this Ajax). You really only need to know two things at this point: • Don't do anything until the xmlHttp. } } Again. Hooking in the Web form So what's left? Actually. Listing 6 shows an example of a method that the server can call based on the values sent in Listing 5. a specific method -. Then the code sets up a PHP script as the destination to connect to. Notice how the URL of the script is specified and then the city and state (from the form) are appended to this using simple GET parameters.value = response. you'll learn more about the stages of an HTTP request than you ever wanted to know. Since the code isn't going to wait around for the server. how to add security to your request -. Handle the server's response function updatePage() { if (xmlHttp. you'll need to let the server know what to do so you can respond to it. sends it to the server. Handling the response Now you need to actually deal with the server's response.is going to take up the bulk of the next article. The final parameter. The data is simple text and can be included as part of the request URL. The method of connection is indicated (GET).responseText property to get the server's response -. that's your instance of the XMLHttpRequest object) allows you to tell the server what to do when it does finish running (which could be in five minutes or five hours). In this case. Next. The first of these -. the ZIP code for the user-entered city and state) to set the value of another form field.xmlHttp. in other words.onreadystatechange = updatePage. The onreadystatechange property of xmlHttp (remember. they're important in good user-interface design. as well as the URL to connect to.ready states -. the code would wait around on the server when the request was made and not continue until a response was received. notice how straightforward and simple this is! Other than getting the asynchronous nature of Ajax into your head. You'll learn how to send POST requests. That's intentional for two reasons: To keep things in the example simple and to show you that sometimes you want users to be able to override what a server says. send() is called with a value of null. The code in Listing 5 is about as easy as it gets. get your head around the basics.readyState property is equal to 4. Since you've added the data to send to the server (the city and state) in the request URL. how to set request headers and content types. your users can still use the form (and even call other JavaScript methods) while the server is processing this request in the background. So this fires off your request and the server can do what you asked it to do.responseText property.using the xmlHttp. Listing 6. a dynamic feel. Responsiveness.

you'll begin with the most fundamental and basic of all Ajax-related objects and programming approaches: The XMLHttpRequest object. That request has a lot more than just a list of books and titles. The result is a back-and-forth that usually involves clicking a button. Listing 7. spend some time thinking about just how powerful Ajax applications can be. Part 2: Make asynchronous requests with JavaScript and Ajax Use XMLHttpRequest for Web requests Level: Intermediate Brett McLaughlin (brett@newInstance. Starting to feel like you've got a handle on things? Good. "What's Web 1. Author and Editor. delineated by each new page you see. you explicitly won't use XMLHttpRequest. As a result. All that's really left is to call that first JavaScript method and start the whole process.0 at a glance First. Think about exactly what asynchronous means. In the next article. waiting for the server. With Ajax and the XMLHttpRequest object. 17 Jan 2006 Most Web applications use a request/response model that gets an entire HTML page from the server. For now. you should first ask.0?" Although you'll rarely hear Web 1. This object is really the only common thread across all Ajax applications and -. you'll find out that sometimes. a bit of dynamic HTML. HTML and XHTML. that's the idea! In conclusion At this point. and even get a handle on the DOM. A request is made to a server and then a response comes back to your browser. when you select an option from a combo box. the callServer() method fires off and the Ajax fun begins. though. until then. and even sets the value of a field when that response comes back. you can clearly see the request and response. In this article." /></p> <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p> </form> If this feels like yet one more piece of fairly routine code. What in the world is that all about? Web 2.0 dispenses with this very visible back-and-forth (to a large degree).. In this article. go to Amazon. and then waiting some more. When you hear the term Web 2. think about JavaScript code running and not waiting on the server to respond to its requests. you can use a request/response model that never leaves users waiting for a server to respond. how to work with HTML forms. you'll put these ideas into practice and I'll give you the details on the code you need to really make applications like this work. You could obviously add a button to your HTML form..0. At the center of this was a lot of technology that you probably already know about: JavaScript. you'll be better served than just having some code you can cut-and-paste and throw into an application that you really don't understand. clicking another button.it is! When a user puts in a new value for either the city or state field. O'Reilly Media Inc. but when you type into a field. In the last article of this series (see Resources for links). Brett McLaughlin shows you how to create XMLHttpRequest instances in a cross-browser way. construct and send requests. I will zoom in from that 10. you were introduced to the Ajax applications and looked at some of the basic concepts that drive Ajax applications. So.com and click a button or enter a search term. enjoy the possibilities of Ajax. to use XMLHttpRequest properly. In the articles to come. However. In fact. how to handle JavaScript-to-server communication.0. don't you think? Take advantage of JavaScript technology like in Listing 7. Kick off an Ajax process <form> <p>City: <input type="text" name="city" id="city" size="25" onChange="callServer(). take this last bit of overview before you dive into code -. and even some DOM (the Document Object Model).com)." /></p> <p>State: <input type="text" name="state" id="state" size="25" onChange="callServer(). you'll learn to master this object. but that's pretty 2001.even when you drag your mouse around the screen. In fact. you can start to get the basic idea of how these applications work and a basic understanding of the XMLHttpRequest object.at least. it is meant to refer to the traditional Web where you have a very distinct request and response model. The Web 2.as you might expect -.make sure you're crystal clear on this idea of the Web 2. As an example. you're probably not ready to go out and write your first Ajax application -. Imagine a Web form that responds to you not just when you click a button. Mastering Ajax. For example. not unless you're willing to do some real digging in the Resources section. you probably get some flashing or flickering as your Web browser's screen is redrawn with this new HTML page.you will want to understand it thoroughly to take your programming to the limits of what's possible. then you're right -. and respond to the server. In this article. visit a site like Google Maps or Flickr (links to both of these .another JavaScript method to listen for and handle a response. What sorts of problems can you run into? What areas do you watch out for? And how will the design of your forms change to account for this new approach in programming? If you spend some real time with these issues. it's actually another complete HTML page.0. though.000-foot view and focus on specific Ajax details.

0. And to any frequent Web surfer. So clearly. rather than an entire HTML page as well. they would all relate to that very simple request/response model.. abort(): Bails out of the current request. these are just a few of the methods and properties you'll use on this object: • open(): Sets up a new request to a server. things can go wrong and this code doesn't provide any error-handling. you've still got to make requests and field responses. many older browsers (believe it or not. you won't learn about an amazing new GUI object or some sort of super-secret approach to creating user interaction. In fact. but all behind the scenes.you'll learn about each method and property in the next several articles. This little object -which has actually been around in several browsers for quite a while -. Listing 3 shows how you might create this object so if something fails. Introducing XMLHttpRequest To make all this flash and wonder actually happen. </script> That's not too hard. The only time you want to get a whole new HTML page is when . you're ready to use the object in your functions. This new feel and paradigm is what you see when someone refers to Web 2. Ajax-powered sites are in Resources). Ajax. it throws out a JavaScript alert. is a good idea of what to do with XMLHttpRequest. responseText: The text that the server sends back to respond to a request. Don't worry if you don't understand all of this (or any of this for that matter) -. the experience is much more pleasant and feels a lot like a desktop application. you just use the new keyword with the object name. That's pretty simple in JavaScript. you need to become intimately familiar with a JavaScript object called XMLHttpRequest. and then assign it to a new instance of XMLHttpRequest. A slightly better approach is to create this object and have it gracefully fail if something goes wrong. As a user.. clunky Web interface. Listing 2. In all of these cases.Web 2. So clearly you need an approach that allows you to make requests and receive responses that include only the data you need. is it? Remember. Of course. Create XMLHttpRequest with some error-handling abilities . though. Obviously. Listing 1. Create a new XMLHttpRequest object <script language="javascript" type="text/javascript"> var request = new XMLHttpRequest(). What you should care about then is how to make these new interactions possible. this ability will make your application feel faster. people are still using old versions of Netscape Navigator) don't support XMLHttpRequest and you need to let those users know that something has gone wrong. But most interactions add details or change body text or overlay data on the existing pages.is the key to Web 2. The simplicity of new First. readyState: Provides the current HTML ready state. you can drag the map around and zoom in and zoom out with very little redrawing.. but it's the redrawing of the HTML for every request/response interaction that gives the perception of a slow. if you saw every method and property of XMLHttpRequest. you need to create a new variable and assign it to an instance of the XMLHttpRequest object. It might not sound exciting. Ajax and a Web 2. On Google Maps. give it a name (like "request"). • • • • send(): Sends a request to a server. Java pseudo-code for creating XMLHttpRequest XMLHttpRequest request = new XMLHttpRequest().. but careful use of this one object can totally change your applications. Notice that each of these methods and properties relate to sending a request and dealing with a response. requests and responses do go on here. So you create a variable in JavaScript with var. To give you a really quick overview. like you see in Listing 1. more responsive. so you don't need anything like you see in Listing 2 (which might be how you'd create this object in Java). you will work with simple requests and simple responses. Error handling In real life. What you should get out of this. Listing 3.0 approach make it possible to send and receive data without updating an entire HTML page. JavaScript doesn't require typing on its variable. well . At that point. for example.0. and bring them back over and over again. and pretty much everything else you learn about in this column for the next several months. when you want the user to see a new page. For example.0.

This is pretty simple. 2. it won't be). } catch (failed) { request = false. Check and see if request is still false (if things are going okay. 3. If you do. </script> Make sure you understand each of these steps: 1. ensure that request is still set to false. You'll use false as a condition that means the XMLHttpRequest object hasn't been created yet. Add in a try/catch block: 1.. Internet Explorer reporting an error . If there was a problem (and request is false).. Now you've got an error-proof piece of code that creates an XMLHttpRequest object and even lets you know if something went wrong. Figure 1. you're going to get something that looks an awful lot like Figure 1. } if (!request) alert("Error initializing XMLHttpRequest!"). Try and create the XMLHttpRequest object. If that fails (catch (failed)). it takes longer to read and write about than it does to actually understand for most JavaScript and Web developers. 2. 4. at least until you try this code in Internet Explorer.<script language="javascript" type="text/javascript"> var request = false. Dealing with Microsoft This all looks pretty good . use a JavaScript alert to tell users there was a problem. try { request = new XMLHttpRequest(). Create a new variable called request and assign it a false value.

In fact. Check out Listing 4 which adds Microsoft support to the code you've already seen. </script> It's easy to get lost in the curly braces. Use false as a condition that means the XMLHttpRequest object isn't created yet. It turns out that Microsoft supports Ajax.Clearly. } catch (failed) { request = false. In fact. but calls its version of XMLHttpRequest something different. some older versions of Internet Explorer use Microsoft. Add in a try/catch block: 1. 3. If that fails (catch (failed)). If there was a problem (and request is false). you need a different approach to deal with Microsoft's browsers.is supposed to move to supporting XMLHttpRequest directly. 2. it calls it several different things. you'll still need to support old browsers. try { request = new XMLHttpRequest(). Don't get too excited. ensure that request is still set to false.XMLHTTP"). Listing 4.0. 3. If that fails (catch (trymicrosoft)): 1. Internet Explorer is hardly an out-of-date browser and about 70 percent of the world uses Internet Explorer. you should see the form you created (without an error message). Try and create the XMLHttpRequest object. something isn't working. } catch (othermicrosoft) { try { request = new ActiveXObject("Microsoft.XMLHTTP creation code.XMLHTTP. Create a new variable called request and assign it a false value. Try and create a Microsoft-compatible object using the newer versions of Microsoft (Msxml2. set to come out late in 2006 -. you won't do well in the Web world if you don't support Microsoft and Internet Explorer! So.XMLHTTP). use a JavaScript alert to tell users there was a problem. In other words. You need to support these two object types (without losing the support you already have for non-Microsoft browsers). If that fails (catch (othermicrosoft)). Make these changes to your code and try things out in Internet Explorer again. it won't be). so that cross-browser code isn't going away anytime soon.version 7. In my case. that results in something like Figure 2. so I'll walk you through this one step at a time: 1.XMLHTTP). Figure 2. If you're using a newer version of Internet Explorer. } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2. try and create a Microsoft-compatible object using the older versions of Microsoft (Microsoft. Internet Explorer working normally . allowing you to use the new keyword instead of all the Msxml2. 4. } } } if (!request) alert("Error initializing XMLHttpRequest!"). Add support for Microsoft browsers <script language="javascript" type="text/javascript"> var request = false.XMLHTTP"). 2. Microsoft's newest version of Internet Explorer -. 2. though.XMLHTTP. Check and see if request is still false (if things are okay. you need to use an object called Msxml2. Microsoft playing nice? Much has been written about Ajax and Microsoft's increasing interest and presence in that space.

3.) That's usually how most Ajax programmers create the XMLHttpRequest object. When JavaScript is coded like that and not put within a method or function body.XMLHTTP"). } } } if (!request) alert("Error initializing XMLHttpRequest!"). } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2. and 4 and notice that all of this code is nested directly within script tags. This means that the code is run sometime before the page is displayed to the user. That said. } catch (failed) { request = false. } catch (othermicrosoft) { try { request = new ActiveXObject("Microsoft. (It's not 100 percent clear from the specification precisely when this code runs and browsers do things differently. } . you're guaranteed that the code is run before users can interact with your page.Static versus dynamic Take a look back at Listings 1.XMLHTTP"). it's called static JavaScript. Move XMLHttpRequest creation code into a method <script language="javascript" type="text/javascript"> var request. Listing 5. you certainly can put this code into a method as shown in Listing 5. still. function createRequest() { try { request = new XMLHttpRequest().

now you can make a request to a server. it could make users mad that your Web application won't run on their browser. swapping out images. In most applications.and the reason most Ajax programmers don't use this approach -.but is still essential to making a connection. Listing 7 shows some JavaScript that grabs the value of the phone number field and then constructs a URL using that data. Use an XMLHttpRequest creation method <script language="javascript" type="text/javascript"> var request. If you have Ajax code running on www. getCustomerInfo() runs.com. but for now realize that code running on your local machine can only make requests to server-side scripts on your local machine. Setting the server URL The first thing you need to determine is the URL of the server to connect to. However.obviously you should know how to construct a URL by now -. selection boxes. This isn't specific to Ajax -. Is that also annoying? Perhaps.XMLHTTP"). even interpreting the data that the server sends back -. the XMLHttpRequest object) can only make requests to the same domain on which it's running.changing the user interface. For that reason alone.</script> With code setup like this. In the case where you use static JavaScript. XMLHttpRequest's only purpose is to allow you to make requests and receive responses. CSS. Listing 6. you'll need to call this method before you do any Ajax work. .XMLHTTP"). it's certainly better than spitting out that same error after they've spent 10 minutes entering information. telling them (in so many words) that they can't use this application. it must make requests to scripts that run on www. Remember. and you fire off some Ajax code when the user enters text in field 14 (way down the form). As a result. Suppose you have a complex form with 10 or 15 fields. // Do something with the request variable } </script> The only concern with this code -. But the user has already spent time entering data in the form! That's pretty annoying and annoyance is not something that typically entices users back to your site. So you might have something like Listing 6. and the like. the user is going to get an error as soon as they hit your page. You'll learn lots more about security and Ajax in an upcoming article.is that it delays error notification. you'll construct this URL from some set of static data combined with data from the form your users work with.is the job of JavaScript.breakneckpizza. Welcome to the sandbox Ajax has a sandbox security model. I encourage you to set up your code statically and let users know early on about possible problems. } } } if (!request) alert("Error initializing XMLHttpRequest!"). tries to create an XMLHttpRequest object. you can begin the request/response cycle. } function getCustomerInfo() { createRequest(). function createRequest() { try { request = new XMLHttpRequest(). For example.com. } catch (othermicrosoft) { try { request = new ActiveXObject("Microsoft. Then an alert is spit out to the user. Everything else -. Sending requests with XMLHttpRequest Once you have your request object.breakneckpizza. } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2. and (for this example) fails. At that point. With XMLHttpRequest ready for use. your Ajax code (and specifically. or other code in your pages. } catch (failed) { request = false.

Remember: Since Ajax code is sandboxed and can only connect to the same domain.gif" alt="Break Neck Pizza" /></p> <form action="POST"> <p>Enter your phone number: <input type="text" size="14" name="phone" id="phone" onChange="getCustomerInfo(). the script name is /cgi-local/lookupCustomer.XMLHTTP"). it fires off the getCustomerInfo() method shown in Listing 8. Opening the request . } } } if (!request) alert("Error initializing XMLHttpRequest!"). } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2. any spaces in the phone number are converted to %20 characters. Listing 8. you really shouldn't need a domain name in your URL. making it possible to pass the characters along in the URL." /> </p> <p>Your order will be delivered to:</p> <div id="address"></div> <p>Type your order in here:</p> <p><textarea name="order" rows="6" cols="50" id="order"></textarea></p> <p><input type="submit" value="Order Pizza" id="submit" /></p> </form> </body> Also notice that when users enter their phone number or change the number.XMLHTTP"). function getCustomerInfo() { var phone = document. var url = "/cgi-local/lookupCustomer.Listing 7.getElementById("phone"). First. Build a request URL <script language="javascript" type="text/javascript"> var request = false. the code creates a new variable named phone and assigns the value of the form field with an ID of "phone. Finally. } catch (othermicrosoft) { try { request = new ActiveXObject("Microsoft. In this example. just append it onto the URL and separate parameters with the ampersand (&) character [the first parameter is separated from the script name with a question mark ( ?)]. For example. If you've never seen the escape() method before.php." Listing 8 shows the XHTML for this particular form in which you can see the phone field and its id attribute. the phone number is appended to this script as a GET parameter: "phone=" + escape(phone). That method then grabs the number and uses it to construct a URL string stored in the url variable. try { request = new XMLHttpRequest(). } catch (failed) { request = false.php?phone=" + escape(phone). The Break Neck Pizza form <body> <p><img src="breakneck-logo_4c. if you wanted to add another parameter. } </script> Nothing here should trip you up.value. it's used to escape any characters that can't be sent as clear text correctly. You can add as many parameters as you need. For example.

Although you can send data using send(). in other words. url. your application essentially becomes unusable until the request you just triggered is responded to. This is just one component of Web 2. you usually get at least one of several forms of notification that you're waiting: • An hourglass (especially on Windows). that's exactly what is needed (see Listing 10).value. • • • • • request-type: The type of request to send. So. even leave the form. and feels faster. What it does not do is actually open a request. but it's a nice bit of self-documentation to always indicate if the request is asynchronous or not.With a URL to connect to.0 here -. There's no spinning beachball or whirling hourglass and no big application freeze. you can configure the request. it's simply called send(). send() takes only a single parameter. does not wait for the server to respond. The end result is an application that doesn't feel clunky or slow. Users can still enter data in a Web form.think Web 1. If you were to monitor the network and data transfer between your XHTML/Ajax page and the script that it connects to. In fact. url: The URL to connect to. then you want to look at sending content through send() (I'll discuss both secure data and XML messaging in a later article in this series). password: If authentication is required. using GET is sufficient (you'll see the situations in which you might want to use POST in future articles). Typical values are GET or POST. The application essentially freezes and sometimes the cursor changes. true). I'll spend significant time on writing and using asynchronous code.php?phone=" + escape(phone). Fortunately. In fact. the client waits for a response from the server. but you can also send HEAD requests.php?phone=" + escape(phone). it let's the original requestor know that it's done (in ways you'll see in just a moment). A teaser on asynchronicity In a later article in this series. For most requests.0. recall that you are already sending data through the URL itself: var url = "/cgi-local/lookupCustomer. you can specify the password here. synchronous request/response model. even when you want an asynchronous request.the client (your browser or the code running on your local machine) makes a request to the server. you can specify the username here. the content to send. request. you're ready to send the request. var url = "/cgi-local/lookupCustomer. When you push a button. While the client is waiting. DSL. to send a request in the example you've seen throughout this article. But before you think too much on that. Put it all together and you usually end up with a line that looks a lot like Listing 9. You send a request and then your application continues on. asynch: True if you want the request to be asynchronous and false if it should be a synchronous request. . but instead is responsive. that. This is what makes Web applications in particular feel clunky or slow -. In a normal request/response model -. Open the request function getCustomerInfo() { var phone = document. you wouldn't see any traffic when the open() method is called. no-waiting world). When you don't need to pass data along through send(). you can also send data through the URL itself. • • A spinning beachball (usually on Mac machines). Typically. The server quietly responds to the request and when it's finished. } Once you have the URL figured out. This parameter is optional and defaults to true. click other buttons. but it clearly wasn't a great choice. All the slick GUI components and Web design paradigms can't overcome a slow. You'll accomplish this using the open() method on your XMLHttpRequest object. but you should get an idea of why that last parameter in open() is so important. but it's a very important one. is all you need to use open(). interactive. This method takes as many as five parameters: Does open() open? Internet developers disagree about what exactly the open() method does. along with the URL. in GET requests (which will constitute as much as 80 percent of your typical Ajax usage). If you've made a request that requires extensive server processing. Listing 9. When you start to send secure information or XML. then just pass null as the argument to this method. This is an optional parameter and has no default value.the lack of real interactivity. That request is synchronous. then this is pretty trivial. the method for sending a request is named more properly than open(). you should specify "true" as the third parameter.getElementById("phone"). username: If authentication is required. It's unclear why the name was chosen. That's the default setting. An asynchronous request though. it's much easier to send data in the URL. you'll use the first three of these.open("GET". Sending the request Once you configure the request with open(). This is an optional parameter and has no default value. that wait might be significant (at least for today's multi-processor.

url. scrolling. JavaScript also treats that function name as a variable. though: What happens when the server has finished processing the request? The answer. This creates an interesting question. you don't have to take any special action writing methods that respond to the server.open("GET". This property allows you to specify a callback method. A request is set up and then made. In other words. request sent to it by XMLHttpRequest. It gives a degree of control to the server. so the server can look up the property when it finishes answering a request. request. Granted. asynchronous or not. in this case.. however. it might call this method while the user is sitting in her chair.Listing 10. clicking a button . So what's the big secret to Ajax and Web 2. it doesn't matter what the user is doing. So if you declare a function called updatePage(). at least as the code stands right now. } Specifying a callback method At this point. true). it might also call the method while the user is typing. request. In other words. Send the request function getCustomerInfo() { var phone = document. request. so the server needs to have some type of instruction on what to do when it's finished processing the Referencing a function in JavaScript JavaScript is a loosely typed language and you can reference just about anything as a variable.regardless of what is going in the Web page itself. you've done very little that feels new. So the code will continue. You must set this property before the request is sent.getElementById("phone").php?phone=" + escape(phone). PHP. as well. you can think of your application as any other app. Listing 11.send(null). not touching the keyboard. that means that the method will exit and control will return to the form. true).onreadystatechange = updatePage. Set a callback method function getCustomerInfo() { var phone = document. moving the mouse. A callback allows the server to (can you guess?) call back into your Web page's code. when the server finishes a request.0? The secret revolves around a simple property of XMLHttpRequest called onreadystatechange.send(null). you can reference the function in your code as a variable named updatePage. This is where that onreadystatechange property comes into play. that little keyword "true" in the open() method sets up an asynchronous request. the server answers a request and then fires off the callback method indicated by the onreadystatechange property. or Perl. Users can keep entering information and the application isn't going to wait on the server. is nothing! Obviously. request. But other than that. Whatever method is specified by that property is then invoked.open("GET".value.php?phone=" + escape(phone). So you need to specify that method in your code as shown in Listing 11. Handling server responses You made your request. and now the server finishes up handling the request. It's a callback because the server initiates calling back into the Web page -. this code resembles programming with Java servlets and JSPs. revolutionary. or asynchronous. Once that occurs. that's not good. For example. This is actually where the asynchronicity comes into play: The user operates the form on one level while on another level. First. be sure you understand the process that you created in this code (review Listing 10 if you need to). The server looks at the onreadystatechange property and figures out what method to call. Additionally.value. the JavaScript method ( getCustomerInfo() in the example) will not wait for the server. your user is happily working in the Web form (while the server handles the request).. var url = "/cgi-local/lookupCustomer. } Pay close attention to where in the code this property is set -. because this is a synchronous request. url. it looks in the XMLHttpRequest object and specifically at the onreadystatechange property. All that's left now is to code the updatePage() which is the focus of the last section in this article.it's before send() is called.getElementById("phone"). var url = "/cgi-local/lookupCustomer. just change the form. request. .

request. to tell you when the server is done. function getCustomerInfo() { var phone = document. Ajax code popping up an alert .getElementById("phone"). true). Code the callback method <script language="javascript" type="text/javascript"> var request = false. Try this code in your own page. var url = "/cgi-local/lookupCustomer. When you enter in a phone number and leave the field. and then pull it up in a browser (if you want the XHTML from this example. } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2. try { request = new XMLHttpRequest(). } } } if (!request) alert("Error initializing XMLHttpRequest!").. } function updatePage() { alert("Server is done!"). Listing 12.php?phone=" + escape(phone).value.open("GET".onreadystatechange = updatePage. Callbacks and Ajax You've already seen how to let the server know what to do when it's finished: Set the onreadystatechange property of the XMLHttpRequest object to the name of the function to run. we'll focus on responding to the server and then taking a typical action -. refer back to Listing 8). You also don't need to worry about any parameters to that method. when the server has processed the request.XMLHTTP"). and again. } catch (othermicrosoft) { try { request = new ActiveXObject("Microsoft. } catch (failed) { request = false. you should see the alert pop up (see Figure 3). request. save the page.changing on the fly part of the form the user sees. request. but click OK and it pops up again . url. it will automatically call that function.send(null). You'll start with a simple method like in Listing 12. In this section.take the user to another URL.. Figure 3. Then.XMLHTTP"). or do whatever else you need to in response to the server. } </script> This just spits out a handy alert.

That's true. } This change checks to ensure that the server really is finished with the process. It's used to figure out if a request has been started. To account for this. that's rarely the case. the only state you need to deal with directly is ready state 4. but it's not the whole truth. if it's being answered. which is as it should be. In fact. As you saw in the last section. Check the ready state function updatePage() { if (request. You need to know about five ready states in your Ajax applications: • 0: The request is uninitialized (before you've called open()). three. but in practice. often some partial data is available from the response. these ready states are used somewhat inconsistently. and then 4. looks up what method to call in the onreadystatechange property of XMLHttpRequest. • • • • 1: The request is set up. HTTP status codes . HTTP ready states Earlier. but the server hasn't finished with its response. Try running this version of the Ajax code and you should only get the alert message one time. 2: The request was sent and is being processed (you can usually get content headers from the response at this point).Depending on your browser. or even four alerts before the form stops popping up alerts.probably not what you intended! For Ajax programming.readyState == 4) alert("Server is done!"). Other browsers report all states. you'll get two. 4: The response is complete. You might expect to always see the ready state move from 0 to 1 to 2 to 3 to 4. the server called updatePage() several times and each invocation resulted in an alert box popping up -. Still others will report ready state 1 multiple times. An HTTP ready state indicates the state or status of a request. then 3. 3: The request is being processed. It's also helpful in determining whether it's safe to read whatever response text or data that a server might have supplied. I said that the server. Some browsers never report 0 or 1 and jump straight to 2. you can get the server's response and use it. the first line in your callback method should be as shown in Listing 13. an important component of the request/response cycle. it calls that method every time the HTTP ready state changes. So what does that mean? Well. As with almost all cross-browser issues. indicating that a server's response is complete and it's safe to check the response data and use it. you've got to understand HTTP ready states first. Listing 13. once finished with a request. but hasn't been sent (before you've called send()). So what's going on? It turns out that you haven't taken into account the HTTP ready state. or if the request/response model has completed.

In addition to the ready state then. and another may return one long string of text. . In the case of the example used in this article. And in the Web world.getElementById("address"). Listing 15. Add some light error checking function updatePage() { if (request.Despite the apparent success of the code in Listing 13. This is just one of many status codes that HTTP requests can receive as a status (see Resources for a link to the complete list of status codes).readyState == 4) { if (request. This allows the server to set this text to virtually anything. one script might return comma-separated values. } Now change the URL in your getCustomerInfo() to a non-existent URL and see what happens. you're ready to process the server's data and that data should be what you asked for (and not an error or other problematic piece of information).status == 200) { var response = request. You're looking for a status code of 200 which simply means okay. Add another status check to your callback method as shown in Listing 14.perfect! This is hardly going to handle every error condition. these are codes that result from a completed response. but is probably not returning the data expected by the client. the server fulfilled the request (meaning the HTTP ready state is 4). In other words. a regular HTML form.responseText. document.status). your server-side code should care if it's being called by Ajax. For instance. Deal with the server's response function updatePage() { if (request.with minimal complication -.split("|"). but reports an error? Remember. document. separated by the pipe symbol. is left intentionally vague.readyState == 4) if (request.innerHTML = response[1]. HTTP codes can deal with the various things that might happen in a request. It's all up to the server. In each of these cases. the server returns a customer's last order and then their address. Reading the response text Now that you made sure the request was completely processed (through the ready state) and the server gave you a normal. else alert("Error: status code is " + request. Details about what the text in responseText looks like. Listing 14. but it's a simple change that covers 80 percent of the problems that can occur in a typical Web application. " "). you also need to check the HTTP status. you can finally deal with the data sent back by the server.what if the server responds to your request and finishes processing. are also common. and received a 404 error code to indicate a page is missing. or any other type of code. With a ready state of 4 and a status code of 200. another pipe-separated values (the pipe is the | character). } else alert("status is " + request.status == 200) alert("Server is done!"). 403 and 401.readyState == 4) if (request.status). Check the HTTP status code function updatePage() { if (request. You should see an alert that tells you the URL you asked for doesn't exist -. Listing 16. This is conveniently stored in the responseText property of the XMLHttpRequest object. else if (request. in terms of format or length. The order and address are both then used to set values of elements on the form.you might add a check or two for other status codes. Listing 16 shows the code that updates the display. typed the URL incorrectly. both indicating secure or forbidden data being accessed. For example. there's still a problem -.getElementById("order").status == 404) alert("Request URL does not exist"). you've certainly entered a request for a URL. } To add more robust error handling -. check out the modified version of updatePage() in Listing 15.replace(/\n/g. it only has the traditional Web-specific methods of reporting information.value = response[0]. okay response (through the status code). a JSP.status == 200) alert("Server is done!").

you'll find it easy to debug and fix even the strangest problems." The second value in the array. Finally. <br />s. These toolkits actually abstract away most of the details discussed in this article and make Ajax programming easier. is the customer's address and it takes a little more processing. That's accomplished through the use of the replace() function along with a regular expression. Truth be told. you'll also see some of the popular Ajax toolkits that are available. you won't be stuck scratching your head and sending an email to support. The resulting array of values is dropped into response. it's awfully hard to figure out what goes wrong in your application if you don't understand what is going on in your application. In coming articles. responseText is all you need. there's quite a bit still to be said about XMLHttpRequest. So don't ignore these details or speed through them. Quite a bit further down the line. Still. it's worth mentioning here. the Document Object Model (DOM). set and read content headers in your request as well as the response from the server. the code needs to replace these with XHTML-style line separators. The answer is.} } First. when your handy-dandy toolkit creates an error. That property contains (can you guess?) an XML response in the event that the server chooses to respond with XML. you'll understand how to encode your requests and even handle XML in your request/response model. The first value -. Toolkits . With an understanding of how to use XMLHttpRequest directly. Since the lines in the address are separated by normal line separators (the "\n" character). Dealing with an XML response is quite different than dealing with plain text and involves parsing. You'll learn more about XML in a future article. You might even wonder why you have to code all this low-level detail when toolkits are so readily available. as you can see in Figure 4. The Break Neck form after it retrieves customer data Before I wrap up. However. In conclusion You might be a little tired of XMLHttpRequest -. the modified text is set as the inner HTML of a div in the HTML form. the responseText is pulled and split on the pipe symbol using the JavaScript split() method.is accessed in the array as response[0] and is set as the value of the field with an ID of "order. especially one that is this simple. you will use this object over and over again in each page and application that you write that uses Ajax. Figure 4. at response[1].the customer's last order -.I rarely read an entire article about a single object. another important property of XMLHttpRequest is called responseXML. For many simple Ajax applications. The result is that the form suddenly is updated with the customer's information. but you'll soon learn about dealing with XML through Ajax applications as well. because responseXML commonly comes up in discussions surrounding responseText. you'll learn to use POST in addition to GET in your requests. and several other considerations.

status). making simple requests and receiving simple responses is all they'll ever need. and most nonMicrosoft browsers. So start coding and check back here in about a month.) Each of these is generally considered part of the plumbing of a request. Digging deeper into HTTP ready states You should remember from the last article that the XMLHttpRequest object has a property called readyState. In this article.getElementById("order").split("|").readyState == 4) { if (request. Listing 1 shows a simple example of this (also in the last article in this series -. However. } else alert("status is " + request. Safari." though. When something goes wrong in your application -.0. and the XMLHttpRequest object Level: Introductory Brett McLaughlin (brett@newInstance. This property ensures that a server has completed a request and typically. I refer to both of these object types simply as XMLHttpRequest. if you have Ajax code running that uses a toolkit. as well as how to use POST requests and send data in several different formats. Part 3: Advanced requests and responses in Ajax Gain a complete understanding of HTTP status codes. In the last article in this series. } } This is definitely the most common (and most simple) usage of ready states. but for developers who want to master Ajax. Listing 1. It will be a great exercise and probably help you understand what's going on a lot better. little detail is recorded about these subjects. look at Part 2 again. So get comfortable with XMLHttpRequest.see Resources).understanding ready states. As you might guess from the number "4. a complete understanding of HTTP status codes. and requests if you want to do more than just dabble in Ajax programming. you'll dig even deeper into this object. how to make a HEAD request.com). 14 Feb 2006 For many Web developers. Every Ajax application uses the XMLHttpRequest object. as a result. you will need to be fluent in ready states. and also deals with return data from that server-side component. a callback function uses the data from the server to update a Web form or page.and things always go wrong -. Author and Editor. In the next article.status == 200) { var response = request. try to rewrite it using just the XMLHttpRequest object and its properties and methods. so you'll want to be intimately familiar with it to make your Ajax applications perform and perform well.innerHTML = response[1]. ready states. Deal with a server's response in a callback function function updatePage() { if (request.responseText. the centerpiece of an Ajax application that handles requests to a server-side application or script.replace(/\n/g.see Resources): • 0: The request is uninitialized (before you've called open()). This matches the common practice you'll find all over the Web and is also in line with Microsoft's intentions of using XMLHttpRequest as the name of their request object in Internet Explorer 7. document. exploring some of its tricker properties (like responseXML). ready states. "<br />"). and the XMLHttpRequest object is required. Brett McLaughlin will show you the different status codes and demonstrate how browsers handle each and he will showcase the lesser-used HTTP requests that you can make with Ajax. I provided a solid introduction to the XMLHttpRequest object. In fact. Opera. O'Reilly Media Inc. Mastering Ajax. I'll look at HTTP ready states first.value = response[0]. or what a 400 status code means can make the difference between five minutes of debugging and five hours of frustration and confusion. (For more on this. document. there are several other ready states (you also saw this list in the last article -. I move beyond the basics in the last article and concentrate on more detail about three key parts of this request object: • The HTTP ready state • • The HTTP status code The types of requests that you can make XMLHttpRequest or XMLHttp: A rose by any other name Microsoft™ and Internet Explorer use an object called XMLHttp instead of the XMLHttpRequest object used by Mozilla. In this article. . status codes. For the sake of simplicity.getElementById("address").are fine unless you count on them to take care of all your problems.

you can get the server's response and use it.readyState). signified by the readyState property 0 (readyState == 0). Note that you've got to check the ready state before open() is called. // Setup (initialize) the request var url = "/boards/servlet/UpdateBoardSales". Unfortunately. Get a 0 ready state function getSalesData() { // Create a request object createRequest(). Figure 1. Ready states in hiding The first ready state. alert("Ready state is: " + request. you need to learn at what state of a request you encounter each ready state. } In this simple example. 4: The response is complete. Furthermore. true).• • • • 1: The request is set up. Figure 1 shows the result of running this application. request. url. the uninitialized ready state is pretty useless in practical applications. First and foremost. request. often some partial data is available from the response. it's rare to see readyState == 0.open("GET". A ready state of 0 .onreadystatechange = updatePage. request. 3: The request is in process. you need to know not only these states. represents an uninitialized request. If you want to go beyond the basics of Ajax programming. Listing 2. but the server isn't finished with its response. but when they occur and how you can use them. 2: The request was sent and is in process (you can usually get content headers from the response at this point). check out Listing 2 which shows how to get the ready state when it's set to 0. Still. As soon as you call open() on your request object. this is fairly non-intuitive and also involves a few special cases. Because you almost always call open() as soon as you initialize your request. but not sent (before you've called send()). in the interest of being complete.send(null). getSalesData() is the function that your Web page calls to start a request (like when a button is clicked). this property is set to 1.

Check the ready state function updatePage() { // Output the current ready state alert("updatePage() called with ready state of " + request. Browser inconsistencies Once you've a basic understanding of this process. It is a trivial task to actually see this process as it takes place. there are very few times when you'll need to make sure that open() hasn't been called. The only use for this ready state in almost-real-world Ajax programming is if you make multiple requests using the same XMLHttpRequest object across multiple functions. check out Listing 3. but nothing has occurred since then to reset the ready state. this doesn't do you much good. checking for a ready state of 0 to ensure that the request object isn't in use can still turn out to be problematic. This code is a great illustration of exactly what onreadystatechange means -. Put it into your Web page and then activate your event handler (click a button. If you have to use multiple functions. but it's not really intended for this use. } If you're not sure how to get this running.the data from the server was used. in this case with a ready state of 1.and you'll see an alert for each ready state. Instead of only running code in your callback if the ready state is 4. When 0 is equal to 4 In the use case where multiple JavaScript functions use the same request object. your request object should go through each of the other ready states in a typical request and response.each time the ready state of the request changes -.readyState == 4) line of code you see in most callback functions comes in. set the onreadystatechange property of your request object to updatePage(). A ready state of 1 Try this code yourself. There is a function that resets a request object called abort().every time the request's ready state changes. and finally end up with a ready state of 4. In that (rather unusual) situation. You should notice some inconsistencies in . tab out of a field. you might want to ensure that a request object is in an uninitialized state (readyState == 0) before making a new requests. For an example of code that does this. Since readyState == 4 indicates a completed request. Viewing an in-progress request's ready state Aside from the 0 ready state. or use whatever method you set up to trigger a request). to do this. just output the ready state every time that your callback is called. Make sure that when you set up your request. you'll often find request objects that are not being used with their ready state still set at 4 -.readyState). it ensures the server is done and it's safe to update a Web page or take action based on data from the server. updatePage() is called and you see an alert. Figure 2 shows a sample of this function being called. This is the best way to follow a request through each of its stages. Figure 2. you'll need to create a function to call from your Web page and have it send a request to a server-side component (just such a function was shown in Listing 2 and throughout the examples in both the first and second articles in this series). Listing 3. try to access your Web page from several different browsers.Obviously. you set the callback function to updatePage(). it might be better to create and use a request object for each function rather than to share the object across multiple functions. That's when the if (request. This essentially ensures that another function isn't using the object at the same time. Your callback function will run several times -.

Remember from the last article that this is the property used to get data from the server. netProfit). Use the response from the server function updatePage() { if (request.0. not see -.5. it's simply the way Safari works. var manCost = getText(manCostEl). /* Figure out the new net profit */ var boardCostEl = document.getElementById("man-cost"). var profitPerBoard = boardCost . in Firefox 1.getElementById("board-cost"). /* Update the net profit on the sales form */ netProfit = Math. Listing 4 is a little more complicated. test on both Internet Explorer and Firefox -. writing code that depends on each interim ready state is a sure way to get different results on different browsers . your callback function can use that data.something interesting. Next I look at the response side. if you access the same application using Safari. you're ready to look at another important piece of the XMLHttpRequest object -the responseText property.5. things are even worse with displayed ready states: • 3 • 4 Last but not least. when using Opera 8. var totalSoldEl = document. Internet Explorer responds with the following states: • 1 • • • 2 3 4 If you have trouble with a request.readyState == 4) { var newTotal = request. this is the very first place to look for problems.1: • 2 • • 3 4 Safari actually leaves out the first ready state and there's no sensible explanation as to why. var boardCost = getText(boardCostEl). Add an alert to show you the request's ready state so you can ensure that things are operating normally. Listing 4. as seen in Listing 1 and Listing 4. you should see -. var manCostEl = document.round(netProfit * 100) / 100. replaceText(totalSoldEl.responseText. } Listing 1 is fairly simple. it places any data that is needed to respond to the request back in the responseText of the request. Here are the states you see on Safari 2. Response data under the microscope Once you understand the various ready states that occur during a request.manCost. For example. var netProfitEl = document.getElementById("net-profit"). both check the ready state and then grab the value (or values) in the responseText property.or rather. . For example. Better yet. Then. Once a server has finished processing a request. var netProfit = profitPerBoard * newTotal. However. you see the following ready states: • 1 • • • 2 3 4 This shouldn't be a surprise since each stage of a request is represented here. newTotal). but to begin. replaceText(netProfitEl. It also illustrates an important point: While it's a good idea to ensure the ready state of a request is 4 before using data from the server.you'll get all four ready states and be able to check each stage of the request.how these ready states are handled.getElementById("total-sold").

use code like that shown in Listing 5 to test the response text of a request. the server has placed a value in the responseText property. At a ready state of 2. for example. Figure 3. To get the most out of this code.Viewing the response text during a request Like the ready state. the responseText property is undefined (see Figure 3). Listing 5. Response text with a ready state of 3 . you'd see an error if the JavaScript console was open as well. } Now open your Web application in a browser and activate your request. Test the responseText property function updatePage() { // Output the current ready state alert("updatePage() called with ready state of " + request.readyState + " and a response text of '" + request. Response text with a ready state of 2 At ready state 3 though. the value of the responseText property changes throughout the request's life cycle.responseText + "'"). To see this in action. use either Firefox or Internet Explorer since those two browsers both report all possible ready states during a request. Figure 4. at least in this example (see Figure 4). as well as its ready state.

document. Of course. } } . see Resources). Trust me.using Ajax and then blocking the user with an alert dialog box is pretty counterintuitive -. 50 percent for a ready state of 2. While using a function like alert() is obviously a bad idea -.working with HTTP status codes. On Opera. A better idea is to provide some feedback to the user that when the ready state is 3. Listing 6. try to set the width of a progress indicator to 25 percent for a ready state of 1. you're ready to add another level of sophistication to your Ajax applications -.readyState == 4) { var response = request.you could update a field on your form or page as the ready state changes.getElementById("order"). To add another layer of control and responsiveness (and particularly more robust error-handling) to your Ajax applications. as you've seen. Callback function that ignores the status code function updatePage() { if (request.innerHTML = response[1]. I'll leave code like this as an exercise rather than include it in this article. and browser to browser. For that reason.the one time you write code that depends on complete data at ready state 3 is almost guaranteed to be the time the data is incomplete. You've probably already seen several of these through your Web browser: • 401: Unauthorized • • 403: Forbidden 404: Not Found You can find more (for a complete list. then you need to check the status codes in a request and respond appropriately. this approach is clever but browser-dependent.split("|"). Time to take a look at status codes. Getting safe data All of the documentation and specifications insist that it's only when the ready state is 4 that data is safe to use. "<br />"). 75 percent for a ready state of 3.getElementById("address"). Still. as in Listing 6.responseText. 200: Everything is OK In many Ajax applications. this is remains incredibly helpful in debugging your application.replace(/\n/g. you'll rarely find a case where the data cannot be obtained from the responseText property when the ready state is 3. a response is forthcoming. you'll see a callback function that checks for a ready state and then goes on to work with the data from the server response. These codes are nothing new to Ajax.value = response[0]. document. For example. A closer look at HTTP status codes With ready states and the server's response in your bag of Ajax programming techniques. They've been around on the Web for as long as there has been a Web. server to server. you'll never get those first two ready states and Safari drops the first one (1). to rely on that in your application is a bad idea -. and 100 percent (complete) when the ready state is 4. However.You'll find that your responses in ready state 3 vary from script to script.

While this is a step in the right direction. In HTTP status codes. change the URL in your request. Ajax applications are almost always written for a specific server-side script. the Ajax programmer.getElementById("order"). Ajax applications on ibm. which indicates various types of errors.split("|"). the ready state will be set to 4 since the server answered the request (even if the answer wasn't what you wanted or expected for your request). document. the only other group of codes to worry about is the 400 family. However. the user is not going to get valid data and might even get a nasty error when your JavaScript tries to use non-existent server data.status). } } With the addition of a few lines of code. you can be certain that if something does go wrong. Redirection and rerouting Before I talk in depth about errors. Check for a valid status code function updatePage() { if (request. it's still a pretty useless message in terms of telling the user or a programmer . So more often than not. including: • 301: Moved permanently • • 302: Found (the request was redirected to another URL/URI) 305: Use Proxy (the request must use a proxy to access the resource requested) Ajax programmers probably aren't concerned about redirections for two reasons: • First. If a script requires authentication and your request does not provide valid credentials. servlet.responseText.replace(/\n/g.com.com cannot make an Ajax-style request to a script running on amazon. As a result. It takes minimal effort to ensure that the server not only finished with a request.situations that occur in very unusual situations in which the oddest conditions are met.com cannot make requests to servlets running on netbeans. In those cases. the server will return an error code like 403 or 401. you can largely ignore the redirection codes altogether.innerHTML = response[1].getElementById("address"). but returned an "Everything is OK" status code. It's certainly true that less than 5 percent of Ajax requests require working with ready states like 2 and 3 and status codes like 403 (and in fact. makes Ajax requests is the domain that must respond to those requests.redirections. For that component to disappear and move somewhere else without you. So a Web page served from ebay. then you'll have content users that return to your site. Look back at Listing 7 and notice that while errors are handled. Errors Once you've taken care of status code 200 and realized you can largely ignore the 300 family of status codes. it's worth talking about something you probably don't have to worry about when you're using Ajax -. novice programmers might wonder what all this fuss is about. your users will get a (questionably) helpful error message rather than seeing a page of garbled data with no explanation. you'll know that a resource has moved (because you moved it or had it moved). your requests aren't able to be redirected to another server without generating a security error. So. but clearly remember the time it didn't. That code is "200" and is reported through the status property of the XMLHttpRequest object.readyState == 4) { if (request. it might be much closer to 1 percent or less).smoothly. document. These cases are important and are called edge cases -. "<br />"). This means that the domain that serves a Web page that Edge cases and hard cases At this point. To make sure that not only did the server finish with a request but that it also reported an OK status. it's only a very generic error message that is output to the user.org.status == 200) { var response = request. While unusual. } else alert("status is " + request. this is the 300 family of status codes. Listing 7. you won't get a status code at all.value = response[0]. while you think about plenty of status codes. You'll usually just have a JavaScript error in the debug console. If you can handle the edge cases -and hard cases -. As a result. edge cases make up about 80 percent of most users' frustrations! Typical users forget the 100 times an application worked correctly. knowing about it is pretty rare. • And an even more relevant reason is: Ajax applications and requests are sandboxed. and never encounter this sort of result. add an additional check in your callback function as shown in Listing 7.This turns out to be a short-sighted and error-prone approach to Ajax programming. or application.

working on the application what actually went wrong.").replace(/\n/g. Figure 6. Listing 8. If you can report 404 errors gracefully. add support for missing pages.status == 200) { var response = request. } else alert("status is " + request.status == 403) { alert("Access denied.innerHTML = response[1].status). document.getElementById("address"). For example. but it's not uncommon in testing for a script to move or for a programmer to enter an incorrect URL.getElementById("order").value = response[0].split("|"). "<br />"). a missing script (which is the case here). user error. } } This is still rather simple.readyState == 4) { if (request. Take a look at Listing 8 which handles missing scripts as well as authentication errors with a specific message. Generic error handling The user has no way to tell if the problem is authentication. This really shouldn't happen much in production systems. but it does provide some additional information."). or even whether something in the code caused the problem. Specific error handling . if a script on the server was removed and you use the code in Listing 7. you're going to provide a lot more help to confused users and programmers.status == 404) { alert ("Requested URL is not found. } else if (request. First. Figure 6 shows the same error as in Figure 5. Some simple code additions can make this error a lot more specific. } else if (request.responseText. Check for a valid status code function updatePage() { if (request. document. Figure 5. you'd see a non-descript error as shown in Figure 5. but this time the error-handling code gives a much better picture of what happened to the user or programmer.

Make a HEAD request with Ajax function getSalesData() { createRequest(). In the spirit of enhanced error handling and information gathering. Print all the response headers from a HEAD request function updatePage() { if (request. as shown in Listing 9. } When you make a HEAD request like this. request. Listing 10 provides a simple callback function to output all the response headers from a HEAD request.onreadystatechange = updatePage. Making the request Actually making a HEAD request is quite trivial. whether the requested resource exists. the server doesn't return an actual response as it would for a GET or POST request. url. I showed you how to make GET requests. true).readyState == 4) { alert(request. var url = "/boards/servlet/UpdateBoardSales". though. request. it begins with handling the status code returned from the server.open("HEAD". consider this one last stop -. you should learn how to make HEAD requests. Instead. In the previous two articles. you might consider clearing the username and password when failure occurs because of authentication and adding an error message to the screen.send(null). you simply call the open() method with "HEAD" instead of "GET" or "POST" as the first parameter. Listing 9. though. Whatever choices you make. Similar approaches can be taken to more gracefully handle missing scripts or other 400-type errors (such as 405 for an unacceptable request method like sending a HEAD request that is not allowed. you'll learn all about sending data to the server using POST requests. . in an upcoming article. Listing 10. You can use several of these to find out about a resource before the server has to process and return that resource. the server only has to return the headers of the resource which include the last time the content in the response was modified. request. and quite a few other interesting informational bits.add HEAD requests to your repertoire. Additional request types If you really want to take control of the XMLHttpRequest object.getAllResponseHeaders()). The easiest thing you can do with a request like this is to simply spit out all of the response headers. or 407 in which proxy authentication is required). This gives you a feel for what's available to you through HEAD requests.In your own applications.

text. Check to see if a URL exists function updatePage() { if (request.perhaps a certain script or servlet is offline quite a bit -. Checking for a URL You've already seen how to check for a 404 error when a URL doesn't exist.readyState == 4) { if (request. To do this. This allows you to determine if a huge amount of data will be sent back to process a request or if the server will try to return binary data instead of HTML. Listing 11. sometimes it's useful to know exactly what is available. } else if (request.you might want to check for the URL before making a full GET or POST request. this has little value. } else { alert("Status is: " + request. it takes just as much time to make the request and see if the URL exists using a HEAD request as it does to make the request using GET or POST than just handling errors as shown in Listing 7. Response headers from a HEAD request You can use any of these headers (from the server type to the content type) individually to provide extra information or functionality within an Ajax application. Still. } } } To be honest.status). Listing 11 shows a sample callback.} } Check out Figure 7."). Figure 7.status == 200) { alert("URL exists").status == 404) { alert("URL does not exist. make a HEAD request and then check for a 404 error in your callback function. you never know when creativity will strike and you'll need the HEAD request! Useful HEAD requests One area where you'll find a HEAD request useful is to check the content length or even the content type. or XML (which are all three much easier to . Additionally. The server has to respond to the request and figure out a response to populate the content-length response header. If this turns into a common problem -. which shows the response headers from a simple Ajax application that makes a HEAD request to a server. so you don't save any processing time.

things will get interesting quickly. and managers are fired because an application goes down 1 percent of the time. The term "stuff" really applies too. and you can ensure that users get valid pages. and edge cases. since most programmers never really consider exactly what happens to their markup when a user's browser is asked to display it: • Does the browser just read the text in the HTML and display it? • • • What about CSS. users look at and activate the Web page.com). As a result. let's dig into the DOM. like Apache HTTPD. HTML is often the last thing they do as they finish up an application or site. users will return to your site and application. CSS. • Add to this the ability to make HEAD requests. you just use the appropriate header name and pass it to the getResponseHeader() method on the XMLHttpRequest object. and (most importantly) surprise them with just how robust and versatile your application is. rather than just in the situation where everything goes exactly right. And. In conclusion For many Ajax and Web programmers..and understand how they differ from browser to browser -. In fact. for simple applications. O'Reilly Media Inc. However. The browser renders the page it receives from the server graphically and textually. or feel more like a desktop. too. In other words. and find out when a file was modified. a HEAD request can allow you to get some basic data without dealing with response data or needing the bandwidth to send that response. A user requests your Web page with a browser like Firefox or Safari. and happy customers. You might even come up with creative functionality based on a ready status and report on a request's status to users and customers. the tremendous amount of "stuff" that happens between steps 4 and 5 is what the focus of this article. and make it public on the Internet or an intranet.getResponseHeader("Content-Type"). To get the content type. use request. you usually file it away as "done" and (hopefully) never really think about it again! That's a great goal when it comes to writing clean. unexpected responses. users have become more advanced. HTML is how programmers start to work on a Web page. While this feels very basic. with various versions of CSS and JavaScript. In these cases. In many applications. without further ado. your application will work all of the time. • If you have a handle on status codes. the material in this article seems fairly advanced. explains its use in Web pages.I want you need to be clear on the process involved in designing and serving Web pages: 1. If you can use Ajax to build a solid foundation in which your application handles errors and problems smoothly. So.you'll be able to debug an application quickly.process in JavaScript than binary data). 14 Mar 2006 The great divide between programmers (who work with back-end applications) and Web programmers (who spend their time writing HTML. Web programmers and markup For most programmers. and JavaScript) is long standing. Before I dive into what you might think happens -. just as common as using HTML is the misconception about what exactly happens to that HTML once it goes to a browser to render to the screen. What is the value in making a HEAD request? What is really a case where you should handle a redirection status code explicitly in your JavaScript? These are good questions. The user's browser makes a request for the HTML to your Web server. just call request.and why it is probably wrong -. 4. or style.again often in an external file? How does the browser handle these items and how does it map event handlers. check for the existence of a URL. 2. their job ends where the Web browser begins. You then upload the HTML to a Web server. It's your job then. Brett McLaughlin introduces the Document Object Model. and styles to that textual markup? It turns out that the answer to all these questions is the Document Object Model. customers expect robustness and advanced error reporting. Like many Web programmers. making HEAD requests adds no functionality and might even slow down a request (by forcing a HEAD request to get data about the response and then a subsequent GET or POST request to actually get the response). across browsers. they are to some degree just icing on the cake. the answer is that these advanced techniques are unlikely to be valuable. especially if the CSS is in an external file? And what about JavaScript -. well-organized pages. However. While these are all strengths of Ajax (and topics we'll cover in subsequent articles). 5. 3. in the event that you are unsure about a script or server-side component. excited. In this article. to go beyond a simple application and that requires a more thorough understanding of XMLHttpRequest. the Web is no longer a place where simple applications are tolerated. you don't want to miss the next article!) Mastering Ajax. the Document Object Model (DOM) bridges the chasm and makes working with both XML on the back end and HTML on the front end possible and an effective tool. and starts to explore its usage from JavaScript.getResponseHeader("Content-Length"). Add to this the visual trickery that I'll talk about in upcoming articles and you'll have thrilled. . Someone (usually you!) creates HTML in a text editor or IDE. there's nothing wrong with wanting your markup to display what it should. This article isn't going to make your applications flashy. functions.. help you highlight text with fading yellow spotlights. and tweak that last bit of placement. Author and Editor. Part 4: Exploiting DOM for Web response Convert HTML into an object model to make Web pages responsive and interactive Level: Introductory Brett McLaughlin (brett@newInstance. you can set your application up to deal with a script's errors. However. you have probably worked with HTML. are up-to-date on their information. • If you can account for the various ready states -. color. So to get the length of a response. once you drop a file of HTML into a directory on your Web server. (Seriously.

This has no bearing on how the browser actually retrieves a page from a Web server. and allow even greater interaction and creativity on your Web sites. What the markup does Some additional thoughts on markup Plain text editing: Right or wrong? Plain text files are ideal for storing markup. These environments often offer shortcuts and help in creating Web pages. Don't worry. for your page. you'll see how the browser takes all this textual organization and turns it into something much more interesting -. In the same vein. it limits your ability to update. When it comes to actually changing your page (which is what most Ajax applications focus on). separating CSS from JavaScript and separating those from the HTML markup requires a format that is easy to. or deleted. Last. at best you're only able to make suggestions. how you must realize the true potential of your Web page. Even the colors and font faces you choose are subject to the monitor of users and the fonts that users install on their systems. formatting. scale images. that's not the largest impact you have on a Web page. text is still very much the best option. but not least. a user can override your style choices. the browser needs the raw HTML so it can apply whatever processing to the page in the browser rather than trusting the server to handle that task. But the organization of that page -. text is a great medium for a document -.and whether they use your CSS. No matter how the user styles that section.. all of these are harder to send across the network than plain text files. More importantly.The problem is that this approach limits a programmer's understanding of what really happens in the browser. When it comes to how a page looks. remember that the promise of new standards like HTML 4.is a secondary consideration. It's easy to think about those tags and selectors and attributes only as little tasks that you do to make a site look just right. Get rid of that limitation. a re-organized chunk of markup . but that doesn't hold true for editing that markup. it's much more dramatic to add text or an entire section to an existing page. When you provide a font size. it's more interesting to actually change the organization that your markup lays out. you're ahead of the game. added to. Once you realize that your markup is really about organization.1 separates content (the data in your page) from . or framework. and a lot more -. There's simply no more efficient approach to take than passing along text. especially when you're using CSS and JavaScript. Binary objects. Rather than think that an h1 causes text to be big. Today's browsers allow users to change the size of text. just as you might have CSS in an external file to your HTML. And a little further on. you can view it differently. each from a file external to an actual page's markup. separate.0 and 1. While you can certainly change the style of an element or piece of text from JavaScript. that means specifically turning text into the visual and graphical page that users view. What you do absolutely control is the structure of your Web page. CSS. simply recall that your HTML is sent across a network to a Web browser every time the page is viewed (putting caching and so forth aside for simplicity's sake). you work with the organization of the page itself. Text over the network: A good thing As already mentioned. and behavior.. and restructure a Web page dynamically using client-side JavaScript. How the user sees that -. When I say that the browser has a hard time representing text. or even JavaScript. I promise this won't turn into a lecture on the beauty of markup. each of which can be changed. realize that you are organizing your content. Text files again are a great way to do just this. well. you probably fire up your text editor and IDE and start to enter HTML. When you provide a CSS stylesheet. Your markup is unchangeable and unalterable and users can't mess with it. The markup has to be in place to be operated upon or styled. Instead. Without getting into the pros and cons. You should also be clear that style and behavior (event handlers and JavaScript) are applied to this organization after the fact. What the programmer does As the typical Web programmer.this all precludes sending any kind of graphical representation of the page to the browser.whether this word is inside that paragraph or in the other div -.is solely up to you. Many folks still prefer good old Notepad or vi (I confess I'm one of those folk) and that's a great option as well.like HTML or CSS -. and bold. their browsers can only retrieve it from your Web server and display it (albeit with a style more in line with the user's tastes than your own).that is transferred over a network hundreds and thousands of times. or some combination of the two -. and so forth.a set of objects.to work on Web page markup. As long as you keep in mind that your markup only provides an organization. their own. img denotes an image. it's worth considering why plain text is absolutely the best choice for storing your HTML (for more on this. The advantages of text markup Before I discuss the Web browser. the organization of your markup is separate from its style. or anything else meta-physical. it's the structure of your page that you operate on. download the CSS or JavaScript for a page (in most cases). While it's great to do your best in styling a page. But you need to stretch your mind beyond that point -instead. Add to that the value that a browser adds to the equation. see Some additional thoughts on markup). graphical representations of the page. the final result is a text file full of markup. div divides a page up into sections. What you do need to understand is exactly what your role in Web development is. It's perfectly acceptable to use an IDE like Macromedia DreamWeaver -or the slightly more intrusive Microsoft® FrontPage® -. in that case. Instead. realize that markup is all about providing this level of organization. While it's nice to change the color of a piece of text. a p indicates that text is in a paragraph. black. think about an h1 as a heading.01 and XHTML 1. In either case. a user's browser can alter those sizes for the visually impaired or scale them down on massive monitors (with equally massive resolutions). So. change.

The tree view of Listing 1 . trees. If markup is stored as text and. for example. Moving to a tree view The answer to this problem -. <img src="come-again. a rather simple and boring HTML page represented as text markup. Simple HTML page in text markup <html> <head> <title>Trees. how do you accomplish that? • Do you add inline styling to the text? • • Do you apply the styling to the HTML text in the browser and just keep up with which content to centered or not center? Do you apply unstyled HTML and then apply format after the fact? These very difficult questions are why few people code browsers these days. defeats much of the advantage of these standards. The complexity comes from the browser actually carrying out the requested action.at least. It's difficult to modify. but hold off on your coding impatience because really understanding exactly what a Web browser does is essential to your code working correctly. Specifically. it's fairly easy to do each of these things. as in Figure 1. The disadvantages of text markup Just as text markup has terrific advantages for a designer or page creator. plain text isn't a great way to store HTML for the browser even though text was a good solution for getting a page's markup in the first place. But when it comes to what the Web browser does. And don't worry. everywhere</h1> <p>Welcome to a <em>really</em> boring page.also often in external files -. Figure 1. its ID.to markup based on the type of element. (Those who do should receive a hearty "Thanks!") Clearly.often from multiple stylesheets in external files -. see Some additional thoughts on markup). its class. • • Change the value of form fields based on JavaScript code. For programmers to separate their HTML from their CSS. The complexity isn't in coding these tasks. Consider these frequent browser tasks: • Apply CSS styles -. To keep these disparate parts separate all the way down to the browser allows the browser the most flexibility in getting the HTML from the server. everywhere</title> </head> <body> <h1>Trees. and its position in the HTML document. Support visual effects like image rollovers and image swapping based on JavaScript code. and ultimately bears little likeness to the dynamic nature of today's Web pages. many of the most savvy Web designers and developers often don't realize what actually goes on "under the hood. code is coming soon. the answer chosen by today's Web browsers -. you want to center the text ( text-align: center) in a p element in the center-text class. it also has rather significant disadvantages for a browser.to different parts of the HTML document. • Apply styles and formatting based on JavaScript code -. trees. A closer look at Web browsers For some of you.gif" /> </div> </body> </html> The browser takes this and converts it into a tree-like structure. text isn't the answer." I'll focus on that in this section. Should the browser rewrite the modified structure to disk? How can it keep up with what the current stage of the document is? Clearly. browsers have a very difficult time directly representing text markup to a user visually (for more on this. Add to this the ability for JavaScript to change the structure of a page and things really get tricky. everything you've read so far may be droll review of your role in the Web development process. clumsy to apply styles and behavior to.is to use a tree structure to represent HTML. then force a browser to retrieve some representation of a page that melds these all back together. Listing 1.presentation and style (usually applied by CSS).</p> <div> Come again soon. Take a look at Listing 1.

at least after it parses the input HTML. ialways begin here when you look at and analyze trees. These objects also have a style property. you're welcome to flip the whole thing upside down. Other than the actual tree background.getting away from having to deal with static text -. So the Web browser not only gets to use an object model to represent your document -. attributes are represented by Attribute types. title is a child of head and then the text "Trees. By using objects. great. that's where the browser resolves some of these problems with text. By using objects to represent each piece of the HTML document. This makes the job of the browser. head and body are said to be branches of html. A few additional terms To carry on with the tree metaphor.I made a few very minor simplifications to keep this article on track. For example. elements in your HTML are represented by an Element object type. So adding a new child element or text is simply a matter of adding a new child to an element's list of children. trees.but can immediately tell what something is by its object type. although that does stretch the tree metaphor a bit. Experts in the DOM or XML will realize that whitespace can have an effect on how text in a document is represented and broken up in the Web browser's tree structure. you'll find out all you need at that time. the first thing you might notice here is that everything in the tree begins with the outer-most. Getting into this does little but confuse the matter. the Web browser can then change those objects' properties. If it helps. each element object has a parent and a list of children. read on and don't worry about it. if not. From the root flow out lines that show the relationships between different pieces of markup. which is the html element. This is called the root element in keeping with the tree metaphor. containing element of HTML. and right on down the line. The operation to figure out whether something is an element or an attribute and then determine what to do with that type of object is simple. Each rectangles is an object. You don't need to memorize all these terms and it is often easier to just visualize the tree structure when you try to figure out what a particular term means. The entire tree is organized like this until the browser gets a structure similar to what you see in Figure 1. so if you know about the effect of whitespace. allow JavaScript to access the document. you'll run into mostly text such as "Trees. and much more. For example. so it becomes trivial to change the style of an element or piece of text on the fly. The head and body elements are children of the html root element. They are branches because they in turn have children of their own. it becomes very easy to change the organization." These are often referred to leaves because they have no children of their own. everywhere" is a child of title. When it becomes an issue. trees. When you reach the extremities of the tree. you might change the height of a div using JavaScript like this: . The value of objects Now that you have some basic terminology in hand. everywhere" and "really. So even though this is at the bottom of the tree. The text in your document is represented by a Text type. it's time to focus more on those little rectangles with element names and text inside (Figure 1). using < for < and > for >) no longer become an issue. For instance. apply styles. much easier. Object types and properties Each possible type of markup gets its own object type. The HTML document is parsed and turned into the set of objects like you saw in Figure 1 and then things like angle brackets and escape sequences (for example.

"Welcome to a really boring Web page. the most common answer would be. you'll probably find some oddities. starting with the way the p element was broken up. the p element has three distinct parts: • The text that comes before the em element • • Tthe em element itself The text that comes after the em element If you mix this ordering up. Strict is sometimes good If you tried the exercise I just mentioned. In fact.</p> </div> </body> </html> Listing 3. even when that's not how you organized the document yourself? Obviously. All of this becomes possible with objects. In this case. re-parse it.you will need to become familiar with the structure of these trees if you want to be able to manipulate them. Even trickier nesting of elements <html> <head> ." You'll find parts of that text.although logical -. and re-display it on the screen. you'll see that this answer -. Even though the "really" text will probably display along with the rest of the p element's text. making sure you keep text with its correct parent (despite how that text might end up looking on screen). you might apply the emphasis to the wrong portion of text. To help cement this in your mind. try to diagram the HTML in Listings 2 and 3. the Web browser can very easily change the appearance and structure of the tree using object properties like this. At this point. Compare this to the complicated sorts of things that the browser must do if it represented the page as text internally. Furthermore. To keep this all straight. but it makes the <span id="bold-text">structure <i>and</i> the organization</span> of the page easier to keep up with. Listing 2. While that seems an unusual request -. In the process. Further. consider the following situations: • What happens to attributes? • • What about text that is broken up with elements. the p element has three object children in the order that those things appeared in the HTML in Listing 1. OK?</h1> <div> <p>This p really isn't <em>necessary</em>. It is very important for you to understand this concept. like "Welcome to a " and " boring Web page". the order does matter! Can you imagine how users would respond to a Web browser if it showed the correct markup. but in a different ordering than you provided in your HTML? Paragraphs were sandwiched in between titles and headings.isn't at all correct. it is a child of em which is a child of p. remember that everything in your markup has to be turned into an object of some type. you'll understand the next few sections a lot better. you probably found some of the potential troubles for a tree-view of your markup (if you didn't exercise. just take my word for it!). For example. To understand this. every change of property or structure requires the browser to rewrite the static file." If you compare this with Figure 1.someDiv. it still is a direct child of the em element. It can have different formatting from the rest of the p and can be moved around independently of the rest of the text. but not all of it. If you ask the typical Web developer what the text content of the p element is. Markup with slightly tricky element nesting <html> <head> <title>This is a little tricky</title> </head> <body> <h1>Pay <u>close</u> attention.especially from an article that contains very little code -. the emphasized text "really" isn't a child element of p. the browser must preserve the order of elements and text. It turns out that the p element has three different child objects and none contain all of the text "Welcome to a really boring Web page.height = "300px". take time to pull open some of your HTML documents and sketch them out as trees. you'll find several of these in Listing 1 and Figure 1.style. In other words. like em and b? And what about HTML that isn't structured correctly (like when a closing p tag is missing)? Once familiar with these sorts of issues.

remember that CSS allows rules to override other rules so if. The resulting tree structure is at best an approximation of what the original page author intended and at worst something completely different.</td></tr> <tr><td>2</td><td>Deal with the <span id="code">head</span> first. To make this well-formed.gif in Figure 3 at the end of this article. It's also worth pointing out that the uniqueness of attribute names makes this list different than the list of child objects. but they also remove ambiguity. you'd still have a problem). an element cannot have two "id" or two "class" attributes. It will help you understand how strictly rules apply to organizing the tree and really help you in your quest to master HTML and its tree structure. So <b><i>bold and italics</b></i> would be illegal because the innermost opening tag -. • The innermost opening tag is matched with the innermost closing tag. More importantly though. Attributes are in fact stored in the object model that a browser uses." Keep in mind that attributes for an element must have unique names. Should bolding be applied first and then italics? Or the other way around? If it seems that this ordering and ambiguity is not a big deal. If you ever loaded your page in a browser and saw something completely unexpected. and so forth.<i> -. you can simply call a method like getAttribute("id") to get the value of an attribute by its name. But <em>do the exercise anyway!</em> </div> </div> </body> </html> You'll find the answers to these exercises in the GIF files tricky-solution. the answers to this <a href="answers. the font for text within b elements was different than the font for within i elements.<title>Trickier nesting.how a browser deals with markup that is not well-formed. (If you switched both. but an attribute is really not the child of the element it appears on -. the DOM defines the objects' types and properties that allow a browser to represent markup. one more topic is worth some time when it comes to how the browser converts markup to a tree representation -. Introducing the DOM So far you've heard that browsers turn a Web page into an object representation and maybe you've even guessed that the object representation is a DOM tree. Well-formed is actually a term largely used in XML and means two basic things: • Every opening tag has a matching closing tag. Just <em>take your time</em>. A p element could have multiple em elements within it.) . so text objects have no lists attached to them for storing attributes. you might have viewed the result of a browser trying to guess what your structure should be and doing the job poorly. still</title> </head> <body> <div id="main-body"> <div id="contents"> <table> <tr><th>Steps</th><th>Process</th></tr> <tr><td>1</td><td>Figure out the <em>root element</em>. every <div> by a </div>. one can contain duplicates (the children of an object) and one cannot (the attributes of an element object). Finally. it simply does the best it can.gif in Figure 2 and trickier-solution. Sloppy HTML Before I move on. but if it were. the fix to this is pretty simple: Make sure your documents are well-formed! If you're unclear on how to write standardized HTML like this. (The next article in this series focuses on the specifics of using the DOM from your JavaScript and Ajax code. then the next innermost opening tag by the next innermost closing tag. the order in which formatting was applied becomes very important. for example. So a div element might have a list that contained an attribute named "id" and another named "class. You can also add attributes and set (or reset) the value of existing attributes with similar method calls. the well-formedness of an HTML page comes into play. you would need to switch either the opening tag order or the closing tag order. Of course. only elements can have attributes. so the list of child objects can contain duplicate items. Don't peek until you take the time to work these out for yourself. What about attributes? Did you run across any problems as you tried to figure out what to do with attributes? As I mentioned. attributes do have their own object type. Study these two rules closely.</td></tr> </table> </div> <div id="closing"> This link is <em>not</em> active.html"><img src="exercise.</td></tr> <tr><td>3</td><td>Work through the <span id="code">body</span>.nested elements and text are not at the same "level" of an attribute and you'll notice that the answers to the exercises in Listings 2 and 3 do not have attributes shown. So every <p> is matched in the document by a </p>. As you'll see in the next article.gif" /></a> would be there.is improperly matched with the innermost closing tag -. This makes the list very easy to keep up with and to access. Each element has a list of attributes available to it. and so forth. but they are a bit of a special case. While the list of children and the list of attributes operate similarly. Therefore. as it's usually easy.<b>. In cases where a browser receives a document that is not well-formed. separate from the list of child objects. consult the Resources for help. They are both rules that not only increase the simple organization of a document. in other words. DOM stands for Document Object Model and is a specification available from the World Wide Web Consortium (W3C) (you can check out several DOMrelated links in the Resources).

they are also included with the sample code! Figure 2. this hasn't been a completely exhaustive coverage of the DOM. highlighting a certain piece of text. or adding a new image element. and attribute nodes. it's a major part of Ajax applications. elements that don't have text content (like the img element). Everything is a node Clearly. In most programming languages. If you followed this Ajax series thus far.it's not. You can simply create a variable and assign it the object you want (as you've already seen): var domTree = document. var phoneNumberElement = document. it should occur to you that you might already be using DOM code. you used the DOM every time you typed document into your JavaScript code.or any other JavaScript -. but is just the beginning.getElementById("phone").it's a specific type of object. If you've programmed much in JavaScript. and create a more interactive experience for your user. a DOM tree is a tree of objects. I'm going to leave you with a bit of a cliffhanger. you need to learn the actual object names for each type of node. For example. you will need to access the object model itself. text that has elements mixed in with it. As a result. this code is pretty useless in and of itself. the line var number = document. var phoneNumber = phoneNumberElement.you can work with those nodes to create such effects as removing an element and its content.getElementById("phone"). detailing how to move within a DOM tree. and figure out about types and casting. And don't forget. but it does demonstrates that every Web browser makes the document object available to JavaScript code and that the object represents the complete tree of markup (Figure 1). and attributes -. There are no types and JavaScript handles creating the variables and assigning them the correct types as needed. In conclusion At this point. get the values of elements and text. you can write code like this: var domTree = document. in fact. Before the next article. To refine the terms you've learned then. There is more to DOM than I've shown you today! The next article in this series will expand upon these ideas and dive more into how you can use the DOM in your JavaScript to update Web pages. Before you can go further. but none of this is necessary in JavaScript. I'll come back to DOM once again in later articles which focus on using XML in your Ajax requests. element nodes. In Ajax applications -. It would be pretty simple to launch into more of the DOM at this point. the document object is important.extend from this basic node type. elements. a form field). these effects take place immediately without communication with the server. but more specifically it is a tree of node objects. Since this all occurs on the client side (code that runs in your Web browser). it will make crafting responsiveness much easier. So even if you didn't realize it. If you get a firm grasp of these concepts and then learn the syntax of JavaScript and the DOM (in the next article). you need to learn another term: node. The more specific types -.value. but that would probably leave you with the impression that the DOM is about code -. You already know that each bit of markup is represented by an object. this article is little more than an introduction to the DOM.The document object First and foremost. iterate through node lists. So become familiar with the DOM.like text. The answer to Listing 2 . it becomes fairly trivial to use the DOM from JavaScript (a later article focuses on the DOM in relation to XML and things are a little trickier). uses the DOM to find a specific element and then to retrieve the value of that element (in this case. but it's more than just any object -. here are the answers to Listings 2 and 3 -. Of course. learn the properties available. think about the organization of a DOM tree and work through the special cases discussed in this article: attributes. try to think about tree structures and work through some of your own HTML to see how a Web browser would turn that HTML into a tree view of the markup.value. make changes to your HTML on the fly. then you've definitely used DOM code for some time now. The end result is often an application that feels more responsive because things on the Web page change without long pauses while a request goes to a server and a response is interpreted. to use the built-in document variable in any piece of JavaScript code running on your Web page. and more. This is remarkably easy. Obviously. a DOM node. So you have text nodes. Also.

The answer to Listing 3 Mastering Ajax.Figure 3. Part 5: Manipulate the DOM Use JavaScript to update your Web pages on the fly .

But. then. A node is. In this series I'll focus on the JavaScript bindings into the DOM.and pay attention to a few special cases and exceptions -your DOM code will work on any browser in the same way. you can use the Java language bindings to work not only with HTML. you might want to do so before you proceed here.. although many of these are not defined by the W3C. almost everything you'll come across is a node. you really need to grasp what a node is. While there is some variance among browsers. The DOM is also a cross-language specification. when the HTML and CSS you've defined for your page is sent to a Web browser. or is the top-most element in the DOM tree (which is a one-time special case for each document. rather than the text files you supplied. So before I get into the specifics of each of these individual types. Also consider that both elements and text have a type. Every element is at its most basic level a node in the DOM tree. Because of that. and focusing on how different they are. as I'll discuss in a later article. you can find welldefined DOM language bindings for C. special characters (like &copy. whose elements work behind the scenes to define your Web pages. Firefox®. The model the browser uses is called the Document Object Model. because that's about as specific as it gets.Level: Introductory Brett McLaughlin (brett@newInstance. is just the first step in taking control of your Web pages. As I explained then.. Author and Editor. The vagueness of "thing" is intentional. Cross browser..all using fairly standardized JavaScript. and even most of the spaces in your HTML and CSS are incorporated into the object model. dynamic Web sites. but instead by third parties. All that said. and more -. which gives you tremendous programming power and flexibility. attributes. such as child elements? Does it have sibling nodes (nodes "next to" the element or text)? What document does each node belong to? Obviously. O'Reilly Media Inc. and even knowing how it represents your HTML and CSS.com). like img. and text in your documents. and take the next step toward updating your Web pages on the fly! If you followed my discussion in this series last month. For instance. well ... Each node also has some fairly well-defined structure to it: does it have a node (or nodes) below it. Of course.. For example. That makes sense because most asynchronous application development is based on writing JavaScript code to run in a Web browser.. For example. Java. that each element and piece of text in a DOM tree has a parent. The W3C defines several language bindings for the DOM. before you get too far into semantics. All the styles. The browser then works directly with the object model. as you'll see in this article. Language bindings are also available for several other languages. So you can use the DOM from any of these languages. the Document Object Model could just as easily have been called the Document Node Model. For instance. but also XML. remove. to learn the actual properties and methods of a node is a piece of cake. in many more environments than just client-side JavaScript. respond to user events and input. you can use it from most of the popular programming languages. and JavaScript. cross language The Document Object Model is a W3C standard (see Resources for links to the W3C). Understanding what a DOM tree is. and is where you use the html element). The type for an element is obviously an element. if you use core DOM functionality -. like "Scroll down for more details" have much in common. a node is just one single thing in a DOM tree. It connects objects representing the elements. Every piece of text is a node. almost every other object defined by the DOM extends the node object. and a DOCTYPE declaration (if you have one in your HTML or XHTML) all are nodes. that element immediately appears in a user's Web browser -. instead. in other words. you need to understand the concept that is represented by a node. much of this sounds pretty abstract. you can modify the user interface on the fly." if you haven't read that article. you need to think a bit abstractly to realize the value of having the node as a common object type. then you got a first-hand look at what goes on when a Web browser displays one of your Web pages. interactive. I do encourage you to check out the DOM language bindings in other languages. you need to learn how to work with the DOM tree for a particular Web page. In fact. Learn how to create. A language binding is simply an API defined to let you use the DOM for a specific language. The specific model for a given Web page is called the page's DOM tree. if you add an element to the DOM tree. The code you write to modify a Web page in Opera will work on Apple's Safari®. that parent is either the child of another element (like when an img is nested inside a p element). In a DOM tree. most people don't know what the term node means. all modern Web browsers support the DOM. This is true whether the code is simple or complex. work with a DOM tree you've taken a huge leap toward mastering rich. and "DNM" isn't nearly as easy to pronounce as "DOM. it might even seem silly to say that the type of an element is . it's translated from text to an object model." so it's easy to understand why the W3C went with DOM. But that's because you're probably thinking about the function of those individual types. Microsoft® Internet Explorer®. Every attribute is a node. Note that the following discussion builds on last month's "Exploiting the DOM for Web response. Remove some text from the DOM tree. an element. In simplest terms. This month he dives even deeper into the DOM. You can change and interact with the user interface through the DOM. which represents a copyright symbol). at least to some degree. Consider. Once you learn how to Acronym pronunciation matters In many ways. . However. In fact. Next. and that text vanishes from the user's screen. and Mozilla®. With JavaScript and the DOM. 11 Apr 2006 Last month Brett introduced the Document Object Model. the type for text is text. housed all in one file or in separate files. values. So the lessons you'll learn here apply to far more than HTML. and a piece of text in HTML. Even comments.without the page reloading. and change the parts of a DOM tree. it's probably not obvious that an element in your HTML. The conceptual node A node is the most basic object type in the DOM.

getElementsByTagName("title")[0]. nodeName and nodeValue really don't apply to all node types (this is also true of a few of the other properties on a node). Things are different if you use a common node type. as text nodes don't have a name.as you would with any other type of node.the name of the element -. I'll look next at exactly what the DOM Node construct has to offer.or its children -. and worry about the type of the node only when you want to do something specific with an element or text. and then begin to work with the elements and text nested within that form. var htmlElement = myDocument. // What's the name of the <html> element? "html" alert("The root element of the page is " + htmlElement. In that case you can simply move from node to node. // Look for the <head> element var headElement = htmlElement. The few other properties really apply to more generic XML documents. Remember. this time to the last node in the childNodes list. named " + headElement. then you have to write completely different pieces of code to move from one type to another. attributes is only useful on an element node. When you just move around in the DOM tree. re-read that last sentence). Rather than simply explain these properties. for example. parentNode returns the node's parent. and text has a parent node. it turns the next node in the parent's childNodes list. Using node properties in the DOM // These first two lines get the DOM tree for the current Web page. I'll talk about these individual types a bit more in the next section. You only have to work specifically with a node type. Unusual properties Most of the above-defined properties are pretty self-explanatory. with the exception of the nodeName and nodeValue properties. you'll use the same operations to move to an element's parent -. when you require something specific from a certain type of node. so let's consider them first.getElementsByTagName("head")[0]. like an element or text. attribute. nextSibling is similar to the previousSibling property. Similarly. similarly. nodeValue returns the text of the node. like an element's attributes. Properties of a node You'll want to use several properties and methods when you work with DOM nodes. labels for input fields. in this node's parent's childNodes list (if that was confusing. • • • • • • • • nodeValue:gives the "value" of the node (see more below).documentElement. This illustrates a key concept: any of these properties can return a null value (which sometimes shows up in JavaScript as "undefined").but the value of an element's nodeValue property is always null. consider a couple of odd questions: What would the nodeName be for a text node? And. The key properties of a DOM node are: • nodeName reports the name of the node (see more below). // Print out the title of the page var titleElement = headElement.The common node type The single task you'll perform more than any other in your DOM code is navigating within the DOM tree for a page. text nodes and attribute nodes don't have any children. every element. this list is only useful when you're dealing with an element. When working with HTML. but since these properties are part of every node. which shows several of the node properties in action. elements have a nodeName -. then you already understand the potential for confusion inherent in these properties. and possibly other HTML elements like img elements and links (a elements). lastChild is another shortcut. childNodes is a list of a node's children. and aren't of much use when you work with HTML-based Web pages. previousSibling returns the node before the current node. firstChild is just a shortcut to the first node in the childNodes list. Attributes have values for both the nodeName and nodeValue properties. If elements and text are completely different types. // and then the <html> element for that DOM tree var myDocument = document. you might locate a form by its "id" attribute. Listing 1. What would the nodeValue be for an element? If these questions stumped you.nodeName). With that in mind. For instance. Now take a look at Listing 1. In other words. So. Thinking about each object in the DOM tree simply as a node allows you to operate much more simply. starting with properties and methods. it returns the node that precedes the current one. . if (headElement != null) { alert("We found the head element.nodeName). the nodeName property for a text node is null (or "undefined" in some browsers. actual input elements. it returns a list of an element's attributes. they're worth mentioning here. as you would probably expect. There will be textual instructions.

the fact that it's not new. When the user clicks a link or takes some other action on the page. You can use Ajax to handle many user interaction events and then to apply the updates to portions of the page. Read on. JavaScript can be difficult to debug. So with all that said. Then. Everything else. a servlet. the portal processes the actionPerformed()method for the target portlet and the doView() methods for each portlet on the page. before we get back to the topic at hand: much of what you see and read about Ajax is not really Ajax. and a Web service) adds to the complexity of the application. make your users happier with such a responsive portal. and the overall application performance. and all the other things that make everyone go "ohh and ahh". The bottom line is to take it slow. Once you get your feet wet and understand how a little effort can produce some effective user enhancements. these tips are generally applicable to most complex applications. Our intention is to equip you with useful information related to using Ajax in your portal applications. DOM updates. there is still a lot going on. Because there are several general Ajax articles already available (see Resources)." OK. Introduction This article introduces you to the idea of integrating Ajax into your portal applications. In certain circumstances. and. and how Google brought this technology into the mind set of every executive and technologist on the planet. we assume you understand the basics of Ajax. Ajax. Only use the portal actionPerformed() method for page-level transitions or to process major state changes. using Ajax can contribute to a cleaner overall architecture of your application. and add a dash of Ajax to a user form or wizard. you will be ready to really add some magic to your portal applications.ibm. you should let the Ajax controller handle all basic user input actions and segmented display updates.Using Ajax with WebSphere Portal Level: Intermediate Karl Bishop (kfbishop@us.ibm. Find an application that could use a little kick. . my friend. we won't tell you not to use it. that's no fun. you might decide that Ajax isn't for you and you will find another article to read. Why Ajax and WebSphere Portal are not a good fit So. Your application might not require extra data updates to the browser between pages. you can. "You bet!" So what this article describes are areas to consider if you decide to inject Ajax into your portal. most of all. why would you not want to use this new fangled paradigm in rich internet applications? All the weekly technical magazines insist that this is the way to go. One of the most expensive actions in a portal is refreshing pages. it aggregates the results and sends the entire HTML document down to the browser. This technique can vastly improve the end-user experience by increasing the responsiveness of individual actions. you already know what Ajax means. you can stand up and say. styling. IBM Doug Phillips (dougep@us.com). and besides. your boss told you to use it because it's "one of our business goals. While caching can reduce a lot of the overhead. This class provides a background communication channel to a server and for the resulting response. you need to provide alternate functionality. is DHTML. and this article tells you how to get started. Having a secondary Ajax controller (such as a servlet or Web service) forces a stronger separation of your model code. so when the call comes down from the CTO's office asking if your portal applications are Ajax enabled. You can improve your portal's performance. This article also prepares you for a future tutorial. Accessibility issues and mobile devices can force you to have redundant code. in its proper sense. how it got its name. Why Ajax and WebSphere Portal are a good fit One of the most expensive actions in a portal environment is to refresh the page. in which we will detail the creation of an Ajax portlet application. While the focus is on portal applications. especially in a cross-browser environment. One quick rant. When applying a full Ajax controller design to your application. but we do want you to know about some potential pitfalls: • Using multiple controllers (for example a portlet. and then to update portions of the page. this stuff is way too cool not to add to your applications.com). it's Dynamic HTML. Well. consists of a single JavaScript object called XMLHttpRequest. Advisory Software Engineer. Senior Software Engineer. without requiring a full portal refresh cycle. including drag-and-drop. You could use Ajax to handle many of the user interaction events in the background. Wait. or DHTML. without requiring a full page refresh. that is. Because many screen readers and other assistive devices do not support JavaScript/Ajax. • • • • Using Ajax forces a lot of logic to be processed on the client. create a cleaner overall portal application architecture. IBM 28 Jun 2006 You have heard the buzz about Ajax and you are wondering if you can use it in your portal application.

then you can share session data between the servlet and the portlet. Figure 1 shows potential Ajax server targets. Figure 1. and the model code are tightly coupled. The servlet or Web service 3. The portlet 2. Under normal circumstances. The servlet. You can either bundle the servlet with the portlet WAR file or include it as part of a stand-alone Web application. • If you do not need this level of coupling and the data and logic to be processed by Ajax are not dependent on the portlet. you are effectively adding multiple controllers to the classic MVC pattern. . There are many JavaScript and DHTML toolkits that provide Ajax abstractions. you use a servlet to perform the communications with the Ajax client. there will likely be a shake-out over the next couple of years. The JavaScript-based client The basic premise of using Ajax in a portal application is the need for a separate controller. This decision has the potential benefit of forcing a cleaner separation of the model logic.Design considerations When you add Ajax to a portal application. portlet. As with all open source projects. Ajax server target possibilities Back to top Ajax toolkits One of the downsides to implementing Ajax is the difficulty in writing good cross-browser JavaScript. there are too many to test to determine which one best fits your needs. The downsides are the added complexity and the unavoidable requirement to break the controller apart into these three aspects: 1. then you can create a stand-alone servlet or Web service to promote reuse. • If you bundle the servlet with the portlet WAR file. In fact.

1. you need to follow a few simple steps. After the global variable is defined. Define a JavaScript reference variable that points to the servlet. you must encode the URL and set the base context. any JavaScript included can safely use it to point to the servlet. Include the servlet JAR file or classes. 2.xml file. as in Listing 1 2.js?v1. Listing 2. <script type="text/javascript" src="<%=renderResponse. Create and define the Ajax servlet. 3. Adding Ajax to a portlet application To implement Ajax in your portal application. DWR. however. Load any external JavaScript files. Because there are many other good ones available. Define the servlet in the web.ibm. <script type="text/javaScript"> var PATH = "<%= request.getContextPath() + "/js/myajax.2")%>" > </script> . 1. Rico.xml <servlet> <servlet-name>MyAjaxServlet</servlet-name> <display-name>MyAjaxServlet</display-name> <description></description> <servlet-class> com. here are the complete and sordid details.MyAjaxServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>MyAjaxServlet</servlet-name> <url-pattern>/Ajax</url-pattern> </servlet-mapping> Define a JavaScript reference to the servlet You need to define the global reference (see Listing 2) in the JSP file so that you have access to the portlet request library. DoJo is preferred because it has an advanced Aspect-like architecture.A few of the most promising and well-designed toolkits that we have used are: Dojo. Create and define the Ajax servlet The process of bundling a servlet with your portlet WAR file is very straight forward. and DWR (see Resources).encodeURL( renderRequest. Servlet mapping in the web. The following discussion assumes that you are bundling your Ajax servlet with your portlet WAR file. Script to encode the URL and set the base context.ajax. var Ajax_SERVLET = PATH + "/Ajax". provides an easy mechanism to reference host-based JavaBeans from the client Javascript. Implement the Ajax framework. Global reference to the servlet. or Direct Web Rendering. Listing 1.1. as in Listing 3. So. even seasoned portlet developers are not always sure of all the details. 4.getContextPath() %>". you need to determine what works for you. Listing 3. </script> Load any external JavaScript files As with any external resource to be added to a portlet page.

// Global XMLHttpRequest variable var <portlet:namespace />xhrFieldsRequest. Namespacing of global JavaScript variables (as in Listing 4) is a good practice because you guarantee unique variable names. For example: <input onChange='eventHandlerFunction()' . You will see the code description in a future.send() Define a call-back function to process the communication states and the response data. o Processing of the response typically consists of parsing the returned XML (or other contents).setRequestHandler(). 1.. type. and xhr. implement these tasks: o Instantiate the XMLHttpRequest (xhr) object variable.onreadystatechange() o Set the servlet. > 4. follow-up tutorial. and using this data to update the DOM tree. 3. you need to . xhr. Typically.2). AJAX communications event model Portal specific concerns There are several issues that you should be aware of when implementing Ajax in a portal application. you force the browser to perform a cache refresh on each load. and when the response has been received. Figure 2 shows how all the pieces fit together.Tip: By using a string argument on the JavaScript parameter. If you have JavaScript that might change frequently. 2. specifically. Using ID attributes ID attributes are often used in Ajax to quickly update a portion of the page. Global JavaScript variables In general. We give you the overview here. If you use an Ajax toolkit. Because all communications are asynchronous. and parameters. Define a function to handle the event.1. Define an event to trigger the process.open(). when a connection is established. which we will cover in the future tutorial. you use a JavaScript event in an input tag. Create a global XMLHttpRequest object variable. even if the same portlet is deployed twice on the same page. such as when the call starts. you must define a unique variable for each Ajax event. but any string will work. Namespacing JavaScript variables. Figure 2. Listing 4. This example uses a version ID ( ?v1.. xhr. Details of this are browser specific. o Set the xhr callback function. avoid using global variables in JavaScript within a portal application because of the fact that the portal aggregates several portlets into a single page. xhr. o This function handles the various communication state changes. Because ID attributes within any HTML tag are global to the DOM. Implement the Ajax framework Making Ajax perform its magic consists of a few boilerplate actions. the abstraction layer will resolve any naming conflicts. this refresh forces browsers not to used old cached code.

In general. you can share session data between the servlet and portlet. While it is possible to use cookies or Ajax calls to a servlet to check and store state information.) You could implement this notification using a floating DIV section display during activity. you need to provide a consistent. In general. There is nothing to stop the user from taking an action in a portlet that can cause a page refresh. Although mostly academic. namespace all ID attributes. this is the normal Session scope. as you can see in Listing 5. To the servlet. Just be sure that anytime a doView() call is processed that any session data holding any Action URLs is regenerated.make sure they are unique. the syntax of the Portlet scope variables is: javax. you should not attempt to store Action URLs in the shared session. Conclusion In this article. we described how and why you would use Ajax in your portal applications. and the problem can be maddening to track down. To access Portlet scope variables from the servlet requires a special namespaced name value that is based on the portlet's ID that was set when it was originally deployed into a portal. or using a simple message on the browser's status bar (although this is considered bad form by some).portlet. the servlet extracts the next page of data from the session. and it must have predefined Action URLs. with a lot of aggregated information stuffed onto a single page. Typically. Make all Ajax calls atomic. Then. Safely namespacing an ID attribute. because they are only valid for the current doView(). It is very difficult to extract this value during development. Because Ajax calls are performed in the background and they do not trigger the activity icon on the browser.<ID>?<NAME> Where: <ID> is the unique identification for the portlet <NAME> name used to set the object in the Portlet session Action URLs Action URLs can be very tricky to deal with when using Ajax. we will show you how to put all the pieces together to produce an Ajax-enabled database administration tool. Otherwise. Sharing session data When you bundle a servlet with your portal application. avoid a dependency on the page's state. If you have duplicate ID attributes. you want to use Application scope when sharing session data.getElementByID ("<portlet:namespace/>header"). You need to make sure that any Ajax activity can be restarted without any dependency on the previous state.p. Stay tuned. An example of when you would want to store Action URLs into the session is an Ajax-driven paging data table that contains Action URL links as part of the data set. Leave that to real portal actionPerformed() calls. You could also integrate a custom theme extension that would display a common Please Wait message for any Ajaxenabled portlet on the page. even though doing this can make your code difficult to read. <h1 id="<portlet:namespace />header">Hello</h1> <script type="text/javascript"> var x = document. </script> State maintenance One pitfall that you can easily fall into is the inherent lack of state management when using Ajax calls in a portal. Listing 5. avoid major state changes based on Ajax. To be safe. In a future related tutorial. visual mechanism to inform the user that something is going on. When the user clicks Next. . (We surely don't want confused users.innerHtml = "GOODBYE!". they can get confused and not know that the application is busy processing some action. Other state issues that can easily trip you up are the back button and bookmarked URLs. the browser generates an Ajax call to the servlet. Activity notification Portal pages are often very busy. Attempting to use an ActionURL that was stored in the session from a previous doView() cycle will cause unpredictable results. then results are unpredictable but generally not what you want. x.