AJAX is the big idea these days. A little bit of AJAX sprinkled into
web development tool box can definitely help you clean up some things.
While there are dozens of new frameworks arising for going full-speed
ahead into AJAX, some of us just want to add some usability to existing
web sites. Here is a simple working prototype for a backend agnostic
way to create a listbox of states and a listbox of counties such that
when the user changes the state, the counties for that state are loaded
in the county listbox.
I know this is not new stuff. People have been doing it for years, but maybe not with Ajax.
-
Some people pop open new windows.
- Some people load content in hidden
frames.
- Some people just load the entire list into the browser when the
page loads for the first time.
- Still others are content to post the
entire page back to the server and cause much pain and sufferring for
users when they must complete all required fields before they can even
select a county of residence or work.
But, now that we all love Ajax, let's look a dead simple example of
doing this with XmlHttpRequest. Here are the tools we'll make use of:
WARNING: The FOLLOWING CODE IS SO SIMPLE YOU MAY BE BLINDED
Step 1: Create a dry as bones HTML UI Page
Name the page
getCounties.html and fill it with this code. Make sure you download the
xmlhttprequest.js file from Andrew's site.
<html>
<head>
<title>Test Ajax Callbacks</title>
<script type="text/javascript" src="xmlhttprequest.js"></script>
<script type="text/javascript" src="populateCounties.js"></script>
</head>
<body>
<form name="locations">
<p>
<b>States:</b> <br />
<select name="states" size="5" style="width:
300px;" onchange="getCounties(this)">
<option
value="12">Florida</option>
<option
value="13">Georgia</option>
</select>
</p>
<p>
<b>Counties:</b> <br />
<select name="counties" id="selCounties" size="5"
style="width: 300px;">
<option value="-1">Please
Select a State to See Counties ... </option>
</select>
</p>
</form>
</body>
</html>
Step 2: Create a Backend Data Provider in ASP 3.0
In real life, you'd probably be calling a datasbase to generate
the return values. In this sample, we'll just use stubs that load
predefined lists. I don't even know if these correspond to FIPS codes
or not, but in real life, you'd make sure they do.
Name this page
getCounties.asp and fill it with this code:
<%
' Stub page that returns dummy county values for an ajax callback
Dim state_id, payload
state_id = Request.QueryString("sid")
payload = "{}"
If Not state_id = "" Then
Select Case state_id
Case "13"
payload = "{1:'APPLING', 2:'COBB', 3:'DE KALB'}"
Case "12"
payload = "{1:'A COUNTY', 2:'B COUNTY', 3:'C COUNTY'}"
End Select
End If
Response.Write payload
%>
Step 3: Create Front-End JavaScript Code to Handle the Events and Make the Callback to getCounties.asp
Finally, we'll create the front-end JavaScript code needed to
manipulate the HTML SELECT object. Name this file populateCounties.js
and put this code in it:
function getCounties(objSel)
{
idx = objSel.selectedIndex;
if (idx != null)
{
var val = objSel.options[idx].value;
var req = new XMLHttpRequest();
if (req)
{
req.onreadystatechange = function()
{
if (req.readyState == 4 && (req.status ==
200 || req.status == 304))
{
// Create an object from the
returned literal code:
var objCounties = {};
try
{
eval("objCounties = " + req.responseText);
}
catch (ex)
{
}
populateCountiesList(objCounties);
}
};
var requestStr = 'getcounties.asp?sid=' + val;
req.open('GET', requestStr);
req.send(null);
}
}
}
function populateCountiesList(objCounties)
{
var counties = document.getElementById("selCounties");
var len = counties.options.length;
for (var i=0; i < len; i++)
{
counties.remove(0);
}
// Add the dummy value for people who don't want to choose a county
counties.options[0] = new Option("Please Select a State to See Counties ... ", "-1");
// add elements from the object
var countyId;
for (countyId in objCounties)
{
counties.options[counties.options.length] =
new Option(objCounties[countyId], countyId);
}
}
Step 4: You Can Test it by Loading it From My Site
To make it easier for you to see in action, I put the code on my
site:
http://apps.ultravioletconsulting.com/projects/AjaxStateAndCounty/getCounties.html
Later, I will put an entire solution with all states and counties.
Recap: Explanation of the Code
- The HTML is just a simple HTML UI that we are all familiar with.
- The getCounties.asp page accepts a state id and then returns a
payload that contains a string of text the is actually valid JavaScript
code. The line {1:'APPLING', 2:'COBB', 3:'DE KALB'} represents
a JavaScript literal object. You can read more about literal notation
in the ECMA-262 documentation or at the link to the JSON site above.
All this means is that this is basically a hash-table, for Perl and
Java folks, or a Dictionary, for VB folks.
- Inside of populateCounties.js, we finally find a GOOD use for the notorious eval()
function. You remember when people used to use eval to do image
rollovers? So do I. I'd rather not remember it though. It gave
JavaScript a bad name, and it never deserved that. But, in our case,
this is a perfect use for eval, because we really want to execute the
string and bring its contents into the scope of the executing block.
After that, we pass it to the populateCountiesList and perform some
more standard, dry-as-bones HTML and JavaScript that we're all familiar
with
So there it is. That's Ajax. You can replace getCounties.asp with
whatever your backend of choice is. Just remember to build a literal
JavaScript object as the payload, and then it's just plain-old HTML and
JavaScript DOM manipulation from that point forward.