Providing User Feedback
In web pages with traditional interfaces, it is clear to the user when the server is busy processing a request; the interface is effectively unusable while a new page is being prepared and served.
The situation is a little different in an Ajax application. Because the interface remains usable during an asynchronous HTTP request, it may not be apparent to the user that new information is expected from the server. Fortunately there are some simple ways to warn that a server request in is progress.
Recall that our callback function is called each time the value of readyState changes, but that we are only really interested in the condition myRequest.readyState == 4, which indicates that the server request is complete.
Let's refer again to Listing 10.3. For all values of readyState other than 4, the function simply terminates having done nothing. We can use these changes to the value of readyState to indicate to the user that a server request is progressing but has not yet completed. Consider the following code:
function responseAjax() {
if(myRequest.readyState == 4) {
if(myRequest.status == 200) {
... [success - process the server response] ...
} else {
... [failed - report the HTTP error] ...
}
} else { // if readyState has changed
// but readyState <> 4
... [do something here to provide user feedback] ...
}
}
A commonly used way to do this is to modify the contents of a page element to show something eye-catching, such as a flashing or animated graphic, while a request is being processed and then remove it when processing is complete.
The getElementById() Method
JavaScript's getElementById() method allows you to locate an individual document element by its id value. You can use this method in your user feedback routine to temporarily change the contents of a particular page element to provide the visual clue that a server request is in progress.
Tip
![]() | Elements within a page that have had id values declared are expected to each have a unique id value. This allows you to identify a unique element. Contrast this with the class attribute, which can be applied to any number of separate elements in a page and is more commonly used to set the display characteristics of a group of objects. |
Suppose that we have, say, a small animated graphic file anim.gif that we want to display while awaiting information from the server. We want to display this graphic inside a <div> element within the HTML page. We begin with this <div> element empty:
<div id="waiting"></div>
Now consider the code of the callback function:
function responseAjax() {
if(myRequest.readyState == 4) {
document.getElementById('waiting').innerHTML = '';
if(myRequest.status == 200) {
... [success - process the server response] ...
} else {
... [failed - report the HTTP error] ...
}
} else { // if readyState has changed
// but readyState <> 4
document.getElementById('waiting').innerHTML = '<img src="anim.gif">';
}
}
On each change in value of the property readyState, the callback function checks for the condition readyState == 4. Whenever this condition fails to be met, the else condition of the outer loop uses the innerHTML property to ensure that the page element with id waiting (our <div> element) contains an image whose source is the animated GIF. As soon as the condition readyState == 4 is met, and we therefore know that the server request has concluded, the line
document.getElementById('waiting').innerHTML = '';
once more erases the animation.
We'll see this technique in action in Lesson 11, "Our First Ajax Application," when we create a complete Ajax application.