Solid Ajax applications, Part 2: Building Ajax back ends

Create a back end for a graphical Ajax application

Back end processing — server-side scripts and programs — can't always be tossed into an Ajax application and behave well. Instead, careful planning to ensure data is sent in an appropriate and efficient form ensures your entire application is cohesive, rather than needlessly complex. Brett McLaughlin explains how a good server-side script complements Ajax behavior.


Brett D. McLaughlin, Sr. (, Author and Editor, O'Reilly Media, Inc.

Photo of Brett McLaughlinBrett McLaughlin has worked in computers since the Logo days. (Remember the little triangle?) In recent years, he's become one of the most well-known authors and programmers in the Java™ and XML communities. He's worked for Nextel Communications, implementing complex enterprise systems; at Lutris Technologies, actually writing application servers; and most recently at O'Reilly Media, Inc., where he continues to write and edit books that matter. Brett's upcoming book, Head Rush Ajax, brings the award-winning and innovative Head First approach to Ajax. His last book, Java 1.5 Tiger: A Developer's Notebook, was the first book available on the newest version of Java technology. And his classic Java and XML remains one of the definitive works on using XML technologies in the Java language.

15 January 2008

Also available in Chinese Russian

In the first article in this series, we built a visually rich front end for displaying a photo gallery, based on Nathan Smith's Hoverbox code (see the Resources section for a link to the original Hoverbox code). In the process, you learned about some fundamental UI principles: the Z-pattern that eyes follow, keeping a page consistent, text decreasing in size in a block moving down the page, and even the difference between readability of serif and sans-serif fonts.

By the first article's completion, you should have had a nice, usable image gallery, as shown in Figure 1, which is where we left the Hoverbox UI in the last article:

Figure 1. The Hoverbox UI from last article
Here's where we left the Hoverbox UI in the last article

In this article, we're going to add the crucial back-end processing, as well as the Ajax-specific code to hook the gallery up to the back end.

Putting Ajax plumbing in place

As I've said before, much of the Ajax work is plumbing: setting up an XmlHttpRequest object, making a call to a server-side program, and getting a response back. The program changes, and details about your request may vary, but the essential setup is the same in every situation:

  1. Create a new request object (preferably in a cross-browser way).
  2. Construct a request URL and possibly POST request data.
  3. Set up a method to callback for the browser when it gets a response from the server.
  4. Send the request.
  5. Construct a callback that runs and does whatever your program needs to do with the server data.

Details of this are covered in various other articles (I'll again refer you to the Resources section), so we'll cruise through this section.

Creating a response object

First, we need a response object, of the XmlHttpRequest variety. Let's create one in a browser-independent way. Listing 1 shows what you need:

Listing 1. Creating a request object
                /* Create a new XMLHttpRequest object to talk to the Web server */
var request = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    request = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    request = false;
@end @*/

if (!request && typeof XMLHttpRequest != 'undefined') {
  request = new XMLHttpRequest();

I saved this into a file called hoverbox-ajax.js, which is where we'll store all the JavaScript for our hoverbox Web application. Then, you'll need to reference this file in the head element of your HTML:

<html xmlns="" xml:lang="en" lang="en">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script language="JavaScript" src="hoverbox-ajax.js"> </script>
<title>Hoverbox Image Gallery</title>
<link rel="stylesheet" href='css/hoverbox.css' type="text/css" 
  media="screen, projection" />
<!--[if IE]>
<link rel="stylesheet" href='css/ie_fixes.css' type="text/css" 
  media="screen, projection" />

We need a server-side spec

At this point, we're ready to actually connect to a server-side script and get some information about each photo. But what does that script take as input? And what format is the output in? Let's try and make things a little more real world and suppose you don't have complete control over your server-side code. Maybe the script that grabs data is already written, and you're just building a new Ajax-enabled front end. Or maybe you're not a PHP person — someone else handles that sort of thing. Either way, you need to know what the script expects and how to communicate with it.

So here's a very simple version of a spec for the script this application will talk with:

Ajax apps are sandboxed

One of the security mechanisms built into the XmlHttpRequest object is sandboxing. Simply put, that means that JavaScript code running on a given domain, like, can only make requests to scripts on that same domain. So if your script is running on your local machine, it can only request scripts running on your local machine (presumably on a Web server on your machine, like Apache or IIS).

For the purposes of this article, that means your JavaScript on your Web page can't call code on because your page isn't getting served on my Web server. You'll need to adjust the URLs in this article for your own setup. You may also want to simplify the server-side script (detailed over the next few sections) so it doesn't use a database, if you don't have access to one.

  • The script exists at a specific URL. For this article, we'll use
  • The script takes a single input: the name of the image to look up. The name shouldn't have a path and shouldn't have an extension. So for an image like img/photo07.jpg, the script wants "photo7.jpg".
  • The script will return the image's name, title, data, and description, all pipe-delimited.

Normally, you'd have enough information to jump right back into your JavaScript. But, so you're not left without a real script, let's take a slight detour and actually build the PHP script (and MySQL database) the spec describes. That way, you can really run this app on your own machine.

A little PHP...

Very rarely do you have the option in designing an application — especially a Web application where you're writing the JavaScript — to determine how either the database you're interacting with or the server-side scripts you're connecting to behave. You're more often given a spec, or perhaps a set of sample input, and you've got to work with that format.

To emulate that to some degree, we're going to build a simple PHP script without much regard for how your Web form will be designed. Consider this a pretty real-world case: someone drops a script in your lap, or at least the details about how that script works. You don't get much input. But that's OK., you're the Web guy, and you know how to work with even the strangest data formats, right?

The PHP script

Because this is really about the client-side and there's a bit of an assumption that you're simply handed the server side spec, Listing 2 gives you the PHP for the server. You can dig into this or ignore it completely. Just make sure it's running somewhere on the same server as your Web page, so you can write JavaScript to access it.

Listing 2. The lookupImage.php script

// Connect to database
$conn = @mysql_connect("", "bmclaugh", "db-1p0j0rdw");
if (!$conn)
  die("Error connecting to MySQL: " . mysql_error());

if (!mysql_select_db("bmclaugh", $conn))
  die("Error selecting database: " . mysql_error());

$image_name = $_REQUEST['image'];
$select = 'SELECT *';$from   = '  FROM image_database';
$where  = ' WHERE name = \'' . $image_name . '\'';

$queryResult = @mysql_query($select . $from . $where);
if (!$queryResult)
  die("Error retreiving image data from the database.");

while ($row = mysql_fetch_array($queryResult)) {
  echo $row['name'] . "|" .
       $row['title'] . "|" .
       $row['date'] . "|" .


This basically grabs the request parameter with the image name, looks it up in the database, and returns all the information about that image, separated by pipes (|s), just like the spec said.

...and a little SQL

To make this a bit more realistic (albeit a little more complex to set up), let's create an SQL database to store information about each image. Here's a screenshot from phpMyAdmin of the table I'm using (see Figure 2):

Figure 2. Table structure for example database
The Hoverbox image gallery table has four columns; very simple

The columns are pretty simple here:

  1. name: The image name, which will match the filenames we're using in the src attribute of each img element in our HTML. Note that we'll want to strip out the img/ prefix, the directory name of where each image is stored, when we connect all this together, so the name for an image referenced as img/image_01.jpg would be "image_01.jpg."
  2. title: The image's title, for example "Sunrise Over the Bay." This data will be the biggest header on the right side of the Web page for each image.
  3. date: Easy enough; the date the image was taken (not necessarily the date the image was stored in the database, by the way).
  4. description: A longer description, related to the image, that we'll show as the main content for each image.

To be clear, this is a very rudimentary table design; even not that great of one, truth be told. Using the image name as a key isn't the best idea, and you could come up with all sorts of other twists. However, that's for an article on database design; the point here is to set up a Web page to JavaScript to server-side to database flow of information, which is what you'll usually be dealing with in "real world" applications.

Blob types don't export well

I've used a BLOB type in this database, and when you do an export, it comes out as binary data — it's basically unintelligible. So don't be disarmed by the weird formatting in the SQL data file.

Inserting sample data

Next, you should insert sample data into your table. I've included a downloadable SQL batch file (see the Resources section) that will create the table and insert five rows full of data. Feel free to use this data for your own database, as typing in 20 descriptions of pictures you didn't take isn't the most enjoyable way to spend an afternoon. The sample includes five rows, and of course you can add more sample data to fill out the rest of the gallery.

Once you have the data in your table, though, you're ready to actually piece together your front-end (the Web form) to your back end (the database).

Sending a request

Now your page has a request object, called request, and you've got a PHP script and database to get data from. So it's time to build the JavaScript function that makes a request to the script and then connect the images in the gallery to that function.

Build a skeleton function first

Before you start dealing with client-to-server connections, you've got to make sure your images call a function. So let's start with a simple placeholder JavaScript function:

function getImageDetails() {
 alert("Image details would get pulled here.");

I put this just below the code that creates a request object, in hoverbox-ajax.js. The function really just a placeholder, but now we can call it and not deal with server-side and Ajax details just yet. It begins by creating a request object and then popping up an informational message box.

A closer look at the images HTML and CSS

Now you need to modify the HTML for your images. Take a close look at how each image in the gallery is represented:

<a href="#"><img src="img/photo01.jpg" alt="description" />
  <img src="img/photo01.jpg" alt="description" class="preview" /></a>

This looks a little confusing at first glance, so let's break it down. First, there's an a tag, which links to nothing (using the # sign as the target). That's just a way to allow for a CSS rule to be put in place when the mouse hovers over the image. Then, there's an img tag. This is the image shown in the gallery by default — the smaller version. Finally, there's the second img, with a class of "preview." Here's the CSS for that class that's relevant here (from css/hoverbox.css):

.hoverbox a
        cursor: default;

.hoverbox a .preview
        display: none;

.hoverbox a:hover .preview
        display: block;
        position: absolute;
        top: -33px;
        left: -45px;
        z-index: 1;

This says that, by default, this second image — which is actually a non-resized, and therefore larger version of the gallery images — is hidden (the display property is set to none). So when the page loads, the images referred to by this second image tag are invisible.

But, when they're hovered over, the .preview rule goes into effect. The image is displayed, shown above the first image (because the second image's z-index is set to 1, a really low number), and moved up a bit so it covers the underlying image completely. The effect is like that shown in Figure 3:

Figure 3. Larger image covering the underlying image
CSS causes an image to get 'bigger' when it's moused over

Calling the JavaScript skeleton function

The behavior we want is to call our JavaScript handler when a user's mouse moves over the image. So that means something like this on every img tag:

<a href="#"><img src="img/photo01.jpg" alt="description" 
  onmouseover="javascript:getImageDetails();" /><img src="img/photo01.jpg"
   alt="description" class="preview" /></a>

Add this to all 20 of your image tags and reload your page. Try reloading your page and checking it out. What do you think? Figure 4 shows this setup in action:

Figure 4. Popping up an alert on the mouseover event
Mousing over an image triggers the getImageDetails() function

Pretty annoying, isn't it? Part of that is the use of an alert. Every time you mouse over an image, an alert pops up, and you have to OK out of it. And that's not to mention how aggravating it was to change all 20 img tags in your HTML to add the handler.

But the bigger problem is usability. Eventually, our getImageDetails() function will need to call a server-side script... for every mouseover! That means even if you're zooming down to the third image of the second column, you're hitting the server for each image your mouse moves over. That's not good at all — way too much processing overhead that's not needed.

Moving the image detail handling to a click

A better approach would be to use the onClick event of the larger image (the one with the "preview" class) so that only when an image in the gallery is clicked will the details be pulled from the server. But that means removing the mouseover handler from 20 images and adding a new one into 20 more images; that's a real mess. Let's take a step back and fix that, keeping in mind that most Ajax applications are heavily dynamic and not dependent on lots of HTML changes.

Below is a simple JavaScript function (which, along with all the rest of your JavaScript, belongs in hoverbox-ajax.js) that runs through all the img tags on a page and then finds all of the images that have a specific CSS class, "preview." Then, the onclick handler of each is pointed to the getImageDetails method. Perfect!

function addImageHandlers() {
 var imagesDiv = document.getElementById("images");
 var imageElements = imagesDiv.getElementsByTagName("img");
 for (var i=0; i<imageElements.length; i++) {
  var class = imageElements[i].className;
  if (class == 'preview') {
   imageElements[i].onclick = getImageDetails;

You can run this by putting it into the onLoad handler of your page's body element, like this:

<body onLoad="addImageHandlers();">

This is a pretty standard "Ajaxian" pattern: adding event handlers programmatically, rather than manually in HTML. The huge upside is that you can make changes easily and not touch all 20 (or 40!) image elements in your code.

Run your page again and notice that you now have to click on an image to get the alert box to pop up. Much better!

Figuring out the image that was clicked

Next, we need our JavaScript function to figure out the name of the image clicked and make sure that fits the format the PHP server-side script expects. The easy part is getting the entire image path to the function, and that's because when any JavaScript function is called, the browser knows which element on the page called that function. You can get access to that element with the this keyword.

To see how this works, change your getImageDetails() method to look like this:

function getImageDetails() {

this will reference the image element that called the function, and the src attribute gives you the image's source attribute. Make these changes, reload your page, and you should see something like Figure 5:

Figure 5. Now the alert gives us the image's src attribute
The this keyword lets us access an element's attributes, like an image tag's src

This is a huge step in the right direction! Now our gallery calls a JavaScript function, and we can get the image's full path.

Stripping path information from the image

There's only one more step before we're ready to call the PHP script on the server. That's turning the image path into a single name, the photo's name, without any path information or extension. So for "file:///Users/bmclaugh/Documents/developerworks/ajax_2-backEnd/hoverbox/img/photo05.jpg," you really just want "photo05" to send to the PHP script. This turns out to be a JavaScript exercise rather than an Ajax-related task, so here's the code, all ready to go:

function getImageName(imagePath) {
 var splitPath = imagePath.split('/');
 var fileName = splitPath[splitPath.length - 1];
 return (fileName.split('.'))[0];

This function takes an image path and retrieves just the name. So now you can go back and update your getImageDetails() function just a bit:

function getImageDetails() {

Save, reload, and you've finally got what you want: a handler that gets the image name and is ready to send it to the PHP server-side script. Figure 6 shows things in action at this stage:

Figure 6. Clicking an image retrieves its name. Perfect!
The image's path is used to figure out the image name itself

Making a request to the server

Now it's a trivial task to send the image name to the PHP script. You'll need some Ajax 101 type stuff to make this happen:

function getImageDetails() {
 var url = "lookupImage.php?image=" + escape(getImageName(this.src));"GET", url, true);
 request.onreadystatechange = showImageDetails;

This is the same function we've been working on, with several notable changes. Now the URL of the PHP script is built, and the image name is appended (escaped, to ensure no funny encoding issues arise in transit). Then the request is set up, the callback function is assigned, and the request is sent. Nothing to it because all the work was already taken care of with the JavaScript functions written in the last section.

Ajax experience required

This article assumes you have some basic Ajax experience and familiarity. If not, you should check out the Resources section. The Mastering Ajax series presents those basics in an easy-to-understand manner and will prepare you for taking things to the application level in this article.

Dealing with the server's response

One of the trickiest things about Ajax applications is that they're spread out over several places: an HTML page, CSS for styling and simple behavior (like popping up larger images in the gallery), JavaScript on the client, PHP on a server, and more. It's not easy to debug these applications.

Because of that, it's almost always easier and better to work at things one piece at a time. For example, rather than writing a callback function that gets the server's response, decodes it, and drops it into the page, it's easier to simply echo back the server's response and make sure it's what you expect. Then, you can add client-side behavior. With that in mind, here's a start at a callback function:

function showImageDetails() {
 if (request.readyState == 4) {
  if (request.status == 200) {
    var response = request.responseText;

Remember, the name of this function has to match what you specified to the request object back in the getImageDetails() function.

Try this out; you should be able to get the response shown in Figure 7. (This assumes you loaded data into your MySQL database or changed your PHP script to return dummy data.)

Figure 7. Clicking an image now returns data for that image
The server's data is pipe-delimited.

Looks good! We've got the data, and now we just need to break it up and put it in its place on the Web form.

Breaking the server data up

The first thing to do is split the data from the server up, using JavaScript's split() function:

function showImageDetails() {
 if (request.readyState == 4) {
  if (request.status == 200) {
    var response = request.responseText;
    var splitResponse = response.split('|');
    var title = splitResponse[1];
    var date = splitResponse[2];
    var description = splitResponse[3];

split() takes a string and splits it into multiple parts, stored in an array. So we can grab the image's title, date, and description. (Note that split() returns a zero-based array. In this case, splitResponse[0] would return the name of the image, which is what we sent the server in the first place.)

Adding IDs to your Web page

It's easiest to access an element on a Web page directly, using an id attribute. Add the following IDs to your Web page, in the section for image details:

<div id="details">
<h2 class="info-title" id="info-title">Sunrise over the bay</h2>
<h3 class="info-date" id="info-date">27 October, 2006</h3>
<p class="info-text" id="info-text">Here is what I experienced when I took this photo.</p>

Getting the right elements

Getting access to these elements — in preparation to change their text — is trivial. You can use getElementById() on each:

function showImageDetails() {
 if (request.readyState == 4) {
  if (request.status == 200) {
    var response = request.responseText;
    var splitResponse = response.split('|');
    var title = splitResponse[1];
    var date = splitResponse[2];
    var description = splitResponse[3];

    var titleElement = document.getElementById("info-title");
    var dateElement = document.getElementById("info-date");
    var descriptionElement = document.getElementById("info-text");

Pretty straightforward. Now all that's left is to actually replace the text of these elements with the server's data.

Replacing text

Changing the text in an element on a Web page is one of those things that should be easy but turns out to be quite tricky. Because the Document Object Model (DOM) stores text as child nodes of the element that text is within, things can get complicated. For example, the text in a p is actually stored in a text node, a child of the element node that represents the p.

So before finishing off the showImageDetails() function, we need a couple of utility functions to make working with the DOM easier. These allow you to clear the text in a node and then insert new text. Add both of these functions to your hoverbox-ajax.js file:

function replaceText(el, text) {
 if (el != null) {
  var newNode = document.createTextNode(text);

function clearText(el) {
 if (el != null) {
  if (el.childNodes) {
   for (var i=0; i<el.childNodes.length; i++) {
    var childNode = el.childNodes[i];

The nice thing is that you can put these in all your JavaScript files (or place them in a file like dom-utils.js or text-utils.js) and use them in all your applications.

Now you can make a few simple additions to your showImageDetails() method to finish it off:

function showImageDetails() {
 if (request.readyState == 4) {
  if (request.status == 200) {
    var response = request.responseText;
    var splitResponse = response.split('|');
    var title = splitResponse[1];
    var date = splitResponse[2];
    var description = splitResponse[3];

    var titleElement = document.getElementById("info-title");
    var dateElement = document.getElementById("info-date");
    var descriptionElement = document.getElementById("info-text");

    replaceText(titleElement, title);
    replaceText(dateElement, date);
    replaceText(descriptionElement, description);

Final test drive

Save everything, reload everything, and you should see a very happy sight: a working, asynchronous, image gallery! Check out Figure 8 to see how mine looks in action:

Figure 8. The completed image gallery
The gallery now shows information about each picture, retrieved from the server.

You can make more changes to this, to tweak things even further. For instance, you can see how the right column of images overlap the text a bit, so you might widen the spacing between the gallery and the text. You could also reformat the date for your locale, or get fancy and format it based on the locale the browser reports it's from. And, of course, the sample data in this article only provides for 5 images, so you could fill the other 15 images out with data too. The sky's really the limit.

Ajax isn't really about technology

This is the second article in this mini-series, and we've got a pretty nifty little Ajax application. However, much of this article has focused on things other than XmlHttpRequest calls like send() and setRequestHeader(). In fact, that's the "dirty little secret" that most experienced Ajax developers realize: Ajax requires pretty simple technologies. A bit of JavaScript — and we're not even using the handy libraries like Dojo or Prototype that make things even easier — and you're probably 90% of the way there. Sprinkle in some DHTML and maybe the DOM, and you're a pro. That is, on the technology side.

The real test of a good Ajax developer is how they handle the pieces of the application and its user interface. How does the application look and feel? (Remember in the last article we discussed how usability is a key component of Ajax applications.) Do the server-side components provide a minimal amount of data in a useful format? Or does your Ajax code have to do all sorts of wrangling on the data, slowing down an interface that should be quick and snappy? And do you make good use of asynchrony? In this application, we changed the application to only retrieve data on a click, so we weren't pulling data for every image the mouse zoomed over. That's good usability: the information is there if desired, but we haven't made assumptions about how the user will work with it.

The developerWorks Ajax resource center
Check out the Ajax resource center, your one-stop shop for free tools, code, and information on developing Ajax applications. The active Ajax community forum, hosted by Ajax expert Jack Herrington, will connect you with peers who might just have the answers you're looking for right now.

In short, Ajax is more about design and architecture than it is pure technology. You can learn the nuts and bolts through other series on developerWorks (like my own Mastering Ajax series, a whopping twelve parts), but it's the crevices of UI design, good user testing, and clear thinking that make for winning Ajax applications. Case in point: Google Maps has no true asynchronous behavior in most implementations, and the code to handle the "Ajax-y" parts of the interface are relatively simple. But there are thousands (millions?) of man-hours devoted to the interface, where things are located on the screen, what options are available, and how they're controlled. Those aren't Ajax technology issues, but they all affect the application.


As we finish up this two-parter, spend a bit of time tweaking the user interface of this application. Move the text information to the left; how does the application feel? What if you require clicking on an image to bring up the details of that image? And difference in overall impression? Play with the server-side component; have it return more information, or less. Do you notice a difference?

Spend enough time with even this simple example, and you'll get a much better sense of what makes an application "usable," as opposed to what makes one "clunky." At the risk of offense, I won't list a lot of existing online clunky sites, but surf around, and you'll find plenty. Why do they feel that way? What lessons can you learn? Take steps along these paths, and you'll quickly be developing amazing Ajax applications of your own.


Sample applicationwa-aj-backendsamples.zip280KB
Sample applicationwa-aj-backendhoverbox.zip282KB
Sample applicationw-aj-backendsampleData.sql.txt12KB



  • Part 1 of this series gets you started on the road to building those amazing Ajax applications of your own.
  • Check out the Hoverbox documentation used as the basis for this article's examples.
  • Hoverbox has an online demo if you want to see where we started.
  • Take the techniques in this article and apply them to Lightbox, an even cooler JavaScript toolkit.
  • The developerWorks Ajax resource center is packed with tools, code, and information to get you started developing slick Ajax applications today.
  • With Web 2.0 being a hot area within development circles, you'll find an ever-growing collection of resources in the Web development zone.

Get products and technologies

  • "Head Rush Ajax" (Brett McLaughlin, O'Reilly Media, Inc.): Takes the ideas in this article and loads them into your brain, Head First style.
  • "Java and XML, Second Edition" (Brett McLaughlin, O'Reilly Media, Inc.): Includes Brett's discussion of XHTML and XML transformations.
  • "JavaScript: The Definitive Guide" (David Flanagan, O'Reilly Media, Inc.): Includes extensive instruction on working with JavaScript, dynamic Web pages, and the upcoming edition adds two chapters on Ajax.
  • "Head First HTML with CSS & XHTML" (Elizabeth and Eric Freeman, O'Reilly Media, Inc.): Learn more about standardized HTML and XHTML and how CSS can be applied to HTML.



developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into Web development on developerWorks

Zone=Web development, XML
ArticleTitle=Solid Ajax applications, Part 2: Building Ajax back ends