XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Remote Scripting with AJAX, Part 2

Remote Scripting with AJAX, Part 2

August 22, 2005

Editor's note: In part one of this two-part series, Cameron Adams created an example application that shows how to use remote scripting to implement the AJAX XMLHttpRequest protocol. Now, in part two, he shows how to create a usable interface for the example app.

The content for this article was excerpted from Cameron's originally published article, which was posted on SitePoint's website last month.

To begin, download the code archive, which contains all of the files you'll need to create the working examples presented here and for part one of this series.

Create a Usable Remote Scripting Interface

The remote scripting model is quite different from the standard page-based interaction that permeates most of the Web, and with that difference comes new usability pitfalls that can too-easily be introduced into your projects. These pitfalls typically arise either from the dynamic manipulation of the interface while the user is accessing it, or from the need to access data that's external to the web page.

Example 1 used remote scripting to validate the receipt number, and to automatically insert data that was retrieved from the database; however, none of this information was used particularly well, nor was it obvious to the user what was going on. Example 2 aims to correct this and other deficiencies in the first example, and make the experience a whole lot quicker, easier, and more understandable for the user. The five tips below explain some of the changes that can be used to turn a bad experience into a good one.

Tip #1: Tell Users Why They're Waiting

Remote scripting is not instantaneous. Regardless of the speed of your web connection, communication time with an external source will vary. So, while communication with a server occurs, it's imperative that you tell the user why they're waiting. (The example PHP scripts use sleep() calls to highlight the waiting periods that can be caused by network traffic or other factors.)

Because remote scripting applications do not make calls using the normal browser interface, the status bar--which normally notifies the user of transfer status and activity--does not function as it normally does. Thus, we have to provide feedback to the user ourselves.

In Example 2, while the receipt number is being verified, a label displays next to the receipt number field to explain the wait.

Figure 1
Figure 1.

The label changes to indicate completion once the XMLHttpRequest connection has finished.

Figure 2
Figure 2.

The status message is initialized just before the XMLHttpRequest connection, when the onchange event for the receipt number field is triggered:

receipt.onchange = onchangeReceipt; 
      
  function onchangeReceipt() 
  { 
 message(this, "loadingMessage", "Verifying receipt number"); 
  
 /* Check for running connections */ 
 if (requester != null && requester.readyState != 0 && requester.readyState
!= 4) 
 { 
   requester.abort(); 
 } 
  
  ...

Once the remote scripting operation has finished, the message is updated to tell the user whether the receipt number was valid or not:

function writeDetails() 
  { 
 if (requester.responseText.charAt(0) == "<") 
 { 
   message(receipt, "statusMessage", "Your receipt details were retrieved"); 
  ... 
  
 else 
 { 
   message(receipt, "errorMessage", "Please enter a valid receipt number"); 
  ...

Updating the message to indicate completion is important, as it provides closure for the user. If the loading message simply disappeared, users could not be certain that it had been successful.

In the two code samples above, the message function is a custom function that dynamically creates a status label for a form element, and positions it visually adjacent to the related element. It also accepts a class for the status label, which allows CSS styles to be applied differently for loading, error, and completion messages:

function message(element, classString, errorMessage) 
  { 
 var messageDiv = document.createElement("div"); 
  
 element.parentNode.insertBefore(messageDiv, element); 
 messageDiv.className = classString; 
 messageDiv.appendChild(document.createTextNode(errorMessage)); 
  
 return true; 
  }

While the XMLHttpRequest process is running, the label animates to indicate that the action is ongoing and still alive. In Example 2, this is performed via CSS styling with an animated GIF, but it could also be effected using JavaScript animation.

The same feature is applied to the form submission button. Again, this alerts the user that some action is being undertaken, and also lets them know that they did click the button, which will help to discourage users from pressing the button more than once:

Figure 3
Figure 3.

To achieve this, simply change the value and the CSS class of the submit button:

submit.className = "submit loading"; 
  submit.value = "Contacting server";

Pages: 1, 2, 3

Next Pagearrow