Introducing AJAHT
"What's in a name? That which we call a rose
By any other word would smell as sweet."
Romeo and Juliet (II, ii, 1-2)
If you have been paying any attention at all to the web development buzz, one of the greatest new technologies must be AJAX. This earth shattering new innovation will save us all. Don't take my word for it. Search Google. AJAX returns thirty-two million hits. Of course a few of those hits might be for the Ajax of Greek mythology or one of many commercial products named for him, like the cleanser.
For those of you too busy to pay attention to all the hype surrounding this astonishing invention, AJAX is an acronym for Asynchronous JavaScript And XML. Of course Ajax committed suicide by falling on his sword, so catchy names may not be all they are cracked up to be. AJAX the technology may not be all the buzz says it's cracked up to be either.
- It isn't really new,
- it won't save the world, and
- it will be over-used and misapplied (like all new things.)
Yet another problem with AJAX is the name itself. AJAX. The X stands for XML which to me implies this is only useful in connection with XML. Nothing could be further from the truth and this is just another unfortunate myth we can only hope will soon fall on its sword as well. Which brings me back to Romeo and Juliet. Would it smell as sweet were AJAX named AJAHT 1? (Asynchronous JavaScript And HTML or Text.)
Blasphemy you say?
No!
The vast majority of the information moved over the Internet, (or more specifically by way of HTTP,) is not surprisingly; "Hyper-Text". That's right! Plain old HTML or text. In fact XML is simply text with a specific structure. Why should a little slice of the text world get the acronym? In any event, both AJAX and AJAHT simply refer to the use of the HTTP Request Object 2 to access remote data. Obviously the "X" was catchier. I doubt we will see anybody using the AJAHT acronym anytime soon. Just remember AJAX does not require XML.
Imagine this often asked scenario:
You have a HTML form. One drop down list box contains a product. The list box was created on page load using some server side script which queried the products table. Let's say a shoe style. After the user selects the shoe style, the user needs to select a related item, such as size and color from other drop down list boxes.
The problem is, each style is not available in every size and there are different colors for each style. We traditionally have had two choices:
- On page load, query the database and build a drop down list for the styles. Also build JavaScript arrays for the available sizes and colors. When a style in selected, we can dynamically create the appropriate drop down list boxes for the sizes and colors which apply to the selected style.
- On page load, query the database and build a drop down list for the styles. When a style in selected, we can make a round trip to the server to query the database and return the sizes and colors in new drop down list boxes.
In the first method, we are essentially loading our entire shoe database to the client side. It can be slow loading and places a heavy demand on the memory of the client browser. It will however be fast when changing the drop down lists for the size and color.
In the second method, we have to make a round trip to the server and rebuild the entire page after querying the database for the sizes and colors. Every time the style is changed we must make another round trip. This method is also more complex to maintain as we must distinguish trips to the server obtain new information from trips to the server to submit the order form.
Using AJAHT we can query the server for just the sizes and colors without rebuilding the entire page and we do not have to send the entire database to the client browser. We only consume data and resources when we need to use them.
I'll show you the finished product and then show you how easy this is to implement.
http://www.rodsdot.com/ee/shoeOrderForm.asp
You'll see there are three drop down lists. Style, Size and Color. Because we will query the database in real time, only those items that are in stock are displayed. If multiple orders were placed by different people, the lists will only show what remains in stock. Not all sizes and colors are available for every show style. The drop down lists for size and color are disabled. The size drop down list indicates the user must choose a style before it will be active. Similarly the color list says you must choose a size before it will be active. I'll select Deck Shoes.

After selecting the style, the size drop down list becomes active and receives focus.

Note that the style selected was sent to the server, the database was queried and only the available sizes for deck shoes were returned for the drop down list. I think you will be pleasantly surprised how fast this occurs. All we are returning is a new drop down list, not a whole page and it happens quite quickly. You will see sizes 7.5, 13.5, 14.5 and 15 are sold out.

After selecting the size, the style and size are sent to the server to perform a real time query for the available colors in that style and size. The only color available for size 9 is Tan.

But for size 7 the shoe is available in Black, Brown and Tan.

And finally, after selecting the color, the shoe selection is complete and we reveal the "Add to Cart" button.

When I think of all the forms I've made that made a round trip to update lists and having to keep track of updates versus a form submission, or the huge delay in loading a massive client side array from the database on page load I cry. This is not only simple and fast, but the code requirements on both the client side and the server side are reduced.
How do we do this Voodoo? It is so easy!
Here is a simple example to help you understand what is happening.
We will have one page which retrieves the HTML for a drop down list box from the server and another page that only has a drop down list box. No other HTML, text or script will be in the drop down list page.
First, the code for the page with the drop down list. Save this to your web server as "dropDownList.html"
<option>Select...</option>
<option value="one">one</option>
<option value="two">two</option>
<option value="three">three</option>
</select>
Second, the page which retrieves the drop down list.
<html lang="en">
<head>
<title>AJAHT Demo One</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
<!--
function getDropDownList(pURL) {
//create the Cross-browser XMLHttpRequest object
if (window.XMLHttpRequest) { // code for Mozilla, Safari, etc
xmlhttp=new XMLHttpRequest();
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType('text/xml');
}
xmlhttp.onreadystatechange=loadList;
xmlhttp.open("GET", pURL, true);
xmlhttp.send(null);
} else if (window.ActiveXObject) { //IE
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
if (xmlhttp) {
xmlhttp.onreadystatechange=loadList;
xmlhttp.open('GET', pURL, true);
xmlhttp.send();
}
}
}
// function to handle asynchronous call
function loadList() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status==200) {
document.getElementById('listContainer').innerHTML=xmlhttp.responseText;
}
}
}
//-->
</script>
</head>
<body>
<div id="listContainer">Click the link...</div>
<p><a href="javascript:void(0);" onclick="getDropDownList('ajahtDropDownList.html')">Load The List</a>
</body>
</html>
Since this might be the first time you have seen the HTTP Request Object used in JavaScript it might look odd or complex. It is really simple, and you will use the same block of code over and over. You can literally cut and paste this code and there are only three items to note:
The URL of the remote page,
The ID attribute of the HTML element in which you will place the results, and
The name of the function to handle the results.
Really since the URL is a parameter, and the loading function could have a generic name, then you only have to take care to get the ID attribute of the HTML element in which you want the results placed correct.
You do not need to know more about the HTTP Request Object than how to use it, which is just copy and paste. If you would like to know more, please see the excellent reference maintained by w3cSchools. In this article I will concentrate on the other considerations of retrieving HTML and text using the object.
If you look at our example code you will see we have one function to get the remote file and another function to handle the results. You might ask, "Why use two functions?" Our call to the server is asynchronous and we do not know when the results are going to be returned. Rather than halt code processing to wait for the results, we tell the HTTP Request Object to call our second function when it receives its results.
We certainly are not limited to returning static HTML. In our shoe order example we are returning dynamic results.
We can change our example drop down list page to query a database.
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open *** Your Connection String Here ***
Set rs = conn.Execute("SELECT style FROM shoeStyles ORDER BY style;")
out = "<select size=""1"" name=""dropDownList"" name=""dropDownList"" onchange=""alert(this[this.selectedIndex].value);"">"
while not rs.eof
out = out & "<option selected value="""& rs("style") &""">"
out = out & rs("style") &"</option>"
rs.movenext
wend
out = out & "</select>"
rs.close
conn.close
Set conn = nothing
response.write out
%>
$link = mysql_connect('server', 'user', 'password');
$db_selected = mysql_select_db('database', $link);
$result = mysql_query('SELECT style FROM shoeStyles ORDER BY style');
$out = '<select size="1" name="dropDownList" name="dropDownList" onchange="alert(this[this.selectedIndex].value);">';
while ($row = mysql_fetch_assoc($result)) {
$out .= '<option value="' . $row['style'] . '">' . $row['style'] . '</option>';
}
$out .= '</select>';
mysql_free_result($result);
mysql_close($link);
echo "$out";
?>
Both examples (ASP or PHP) simply connect to the shoe inventory database and get the shoe styles to build a drop down list.
In our shoe order example we are using a more complicated script to determine how to generate the drop down lists. In fact, one could say our code is schizophrenic. The list boxes generated have multiple personalities depending on how the code is called.
If the show size list is called with no URL parameter for the shoe style, then the list returned is a disabled select telling the user to select a shoe style. When called with a shoe style parameter can return the corresponding shoe sizes or it can return an "Out of Stock" message. This has another benefit. If the main page is refreshed, the drop down lists state will be maintained if the URL contains the parameters for the lists. This can be seen in the live example by clicking the "Send to Cart" button.
Here is the pseudo code:
if the style is empty build a disabled select saying to pick a style.
if the style is not empty then get the matching in stock sizes from the database.
if there are no in stock sizes build a read-only text box saying,
"Out of Stock"
else loop through the styles to build a drop down list,
if the size parameter is not empty mark the correct option selected.
Each drop down list also has an onchange event. That is used to send the selected item from that list, back to the server to be used to retrieve the correct values in the next drop down list.
The code for the onchange event for the styles drop down list is as follows:
styleId=pStyle;
var gURL = 'shoeOrderFormGetAvailableSizes.php?style='+styleId;
//create the Cross-browser XMLHttpRequest object
if (window.XMLHttpRequest) { // code for Mozilla, Safari, etc
xmlhttp=new XMLHttpRequest();
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType('text/xml');
}
xmlhttp.onreadystatechange=loadSizes;
xmlhttp.open("GET", gURL, true);
xmlhttp.send(null);
} else if (window.ActiveXObject) { //IE
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
if (xmlhttp) {
xmlhttp.onreadystatechange=loadSizes;
xmlhttp.open('GET', gURL, true);
xmlhttp.send();
}
}
// order is not ready if we just changed item style
document.getElementById('buttons').style.display='none';
if (sizeId!='') {
// we could have changed the shoe style after selecting a size - reset the colors
getAvailableColors('');
}
}
// function to handle asynchronous call
function loadSizes() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status==200) {
document.getElementById('sizes').innerHTML=xmlhttp.responseText;
if (xmlhttp.responseText.indexOf('disabled')<=0) {
document.getElementById('size').focus();
}
}
}
}
This code simply executes the HTTP Request Object to retrieve the "Sizes" drop down list using the style id passed from the "Styles" drop down list.
Note also that if we select the style, and size, then change the style list box, the other drop downs need to be reset. Since we are responding to that change and are retrieving the sizes, then the "Colors" drop down list needs to be reset to its uninitialized state. Other wise we may show colors that are not available. We handle that by making a call to the get available colors function with an empty size parameter.
Each of the drop down list pages is very simple and self contained. Very easy to debug and maintain. Similarly, the client side code for the change events is nearly identical not only for each list, but for any page where we need to use the HTTP Request Object.
That means the form handler when the shoe order page is finally submitted will also be much simpler as it need not be concerned with drop down list state and only handles the form submission.
It isn't often you can get a better end user experience, reduced time, and simpler code all in one technique which might explain why the use of the HTTP Request Object has become so popular. Like all popular things in information technology, it seems the HTTP Request Object must have an acronym. There is nothing wrong with AJAX and it sounds much snappier that AJAHT. I know AJAHT will never make it in the world of IT acronyms, but I do hope that developers will remember there is much more to the HTTP Request Object than retrieving XML. As long as the page requested is retuning HTML or text this method will work.
I bet you can find a number of places in your web development where the performance and maintenance gains you can achieve with asynchronous JavaScript calls using the HTTP Request Object will pay you many dividends. Just call it AJAHT so your fellow developers will think you know something exciting they don't.
ASP Source Code
PHP Source Code


