File Under: Ajax

Build an Ajax Dropdown Menu

If you hang out with designers and developers at all, then you’ve probably heard the term “Ajax” by now. It’s the official buzzword of Web 2.0. But it’s also an extremely useful web development technique.

In the course of this tutorial, we’re going to look at what Ajax can do. Then we’ll use a JavaScript class to simplify your first steps toward the ultimate in speedy user interactivity.

First, what is Ajax? It stands for Asynchronous JavaScript And XML. In simple speak, Ajax allows us to use JavaScript to grab an XML file (or any other text) without reloading the whole web page.

Ajax has been used for a lot of things, but it is most impressive when many small updates are needed in a short period. Think streaming stock quotes or draggable maps.

In our example, we’ll use a pair of dropdown menu boxes (SELECT tags in HTML). A selection in the first box affects our list of choices in the second box. It’s not exactly cutting edge (Thau did something similar using JavaScript), but it’s a proof of concept.

Before we get started, here’s the stuff you’ll want in your toolbag:

1. A love of extremely basic HTML.

2. Willingness to consult Thau’s Javascript Tutorial if you get confused.

3. “Http“, a caching XmlHttpRequest wrapper, which you can download to immediately make your life simpler. Plus, if you get into advanced Ajax programming, you may like the caching that is built into this Javascript class.

But that’s the future. Let’s talk about now, alright? Ajax on three. One, two, three… Ajax!

Before we do any JavaScript Ajax voodoo, let’s setup our HTML.


<html>

<head>

<!--

	Javascript Ajax voodoo will go here

-->

</head>

<body>

<form name="frmSelect">

<p>

<select name="country" onChange="handleOnChange(this);">

<option>Select country</option>



<option>France</option>

<option>Germany</option>

<option>Spain</option>

</select>

</p><p>



<select name="prez">

<option>Select head of government</option>

</select>

</p>

</form>

</body>

</html>

Here we have created an HTML form containing two dropdown menus. The dropdowns use the SELECT tag, which can contain several options.

The first dropdown has four options: Select country, France, Germany, and Spain. Notice the onChange part of this dropdown:

onChange="handleOnChange(this);"

This will become important later.

The second dropdown has only one option: Select head of government.

What we want to accomplish with our Ajax call is to get the three most recent heads of government for each country and load them into the second dropdown whenever the user changes the first dropdown.

Sounds simple enough, but how are you on recent European presidents and chancellors? One great thing about Ajax is that we can grab content only when we need it. So, we’ll connect ourselves to some sort of feed that will give us the head of government for a particular country when we need it.

For the purpose of this example, our feed will be plain text files stored in the same directory as our web page. So, copy the following lines to their own text files.

France.txt:

Valéry Giscard d'Estaing|François Mitterrand|Jacques Chirac

Germany.txt:

|Helmut Kohl|Gerhard Schröder|Angela Merke

Spain.txt:

|Felipe González Márquez|José María Aznar López|José Luis Rodríguez Zapatero

Notice how the lines contain names separated by vertical lines? Those lines are called “pipes,” and the pipe symbol has its own keystroke on your keyboard. Just hold Shift and look for the backslash (). So, the plan of attack is that whenever Germany is selected (for example), we’ll make an Ajax call to retrieve Germany.txt, get rid of those pipes, and put the names in the second dropdown box.

Now that we’re ready for the Ajax voodoo, let’s get to the nitty gritty on the next page.

Packin’ boxes

If you haven’t downloaded request.js, the Ajax wrapper Javascript class, grab it now and put it in the same directory as the web page with the two dropdowns.

Now, find this line in your document:

<!-- Javascript Ajax voodoo will go here -->

And replace it with these lines:


<script src="request.js"></script>

<script>

function handleOnChange(dd1)

{

  var idx = dd1.selectedIndex;

  var val = dd1[idx].text;

  var par = document.forms["frmSelect"];

  var parelmts = par.elements;

  var prezsel = parelmts["prez"];

  var country = val;

  if (country != "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

  }

}

function fillPrez(xmlreply, prezelmt)

{

  if (xmlreply.status == Http.Status.OK)

  {

   var prezresponse = xmlreply.responseText;

   var prezar = prezresponse.split("|");

   prezelmt.length = 1;

   prezelmt.length = prezar.length;

   for (o=1; o < prezar.length; o++)

   {

     prezelmt[o].text = prezar[o];

   }

  }

  else

  {

   alert("Cannot handle the Ajax call.");

  }

}

</script>

Now that’s a big chunk of code.

This line reads in the Ajax wrapper class that does the heavy lifting:

<script src="http://www.wired.com/images/archiveequest.js"></script>

The handleOnChange function is called whenever the first dropdown is changed. Remember how I said that onChange stuff would be important?

Lastly, the fillPrez function takes the output from the Ajax call and puts the names into the second dropdown.

Let’s look through it a little closer.

This sequence of Javascript looks through the first dropdown, finds which one is selected, and returns the country name into a variable named, appropriately, country:

var idx = dd1.selectedIndex;

var val = dd1[idx].text;

var par = document.forms["frmSelect"];

var parelmts = par.elements;

var prezsel = parelmts["prez"];

var country = val;

Then, if an actual country is selected, an Ajax call is made for the name of the country with .txt at the end. We supply our other function, fillPrez, to be the “callback” function. Whatever comes out of our Ajax call, we want it to go to fillPrez.


if (country != "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

}


We also pass along our second dropdown box, so that fillPrez will know which dropdown to fill.

The first thing that happens in fillPrez is that we make sure that our Ajax call actually found the list of heads of government:

if (xmlreply.status == Http.Status.OK)

If it didn’t, we let the user know there’s an error:

alert("Cannot handle the Ajax call.");

If we’re good to go, then we grab the list of names and split it apart on those pipes:


var prezresponse = xmlreply.responseText;

var prezar = prezresponse.split("|");

We clear out the second dropdown, except for the first option (“Select head of government”):


prezelmt.length = 1;


Then we add each of the names into the dropdown:


prezelmt.length = prezar.length;

    for (o=1; o < prezar.length; o++)

    {

      prezelmt[o].text = prezar[o];

}

You have now successfully created an Ajax call. Your Javascript code made a connection to your server, grabbed a text file, split apart the names in the file, and plopped the resulting data right into your dropdown box.

See it in action and download the code at my website.

There are a number of ways you could expand this code. A few examples:

1. When someone chooses a head of government, you could redirect the user to the politician’s web page.

2. You could show information about the head of government and their time in office. Extra points for using Ajax to grab the selected politician’s bio.

3. You could also give up on the heads of government idea and instead fill the second dropdown with cities, states or provinces. Or maybe you could show fast food chain locations.

You get the idea. There are a plethora of possibilities.

Now, if you aren’t impressed since Thau did this in 1998 and he didn’t need no Ajax, remember this is a proof of concept. Rather than a text file, consider setting up a more dynamic feed using PHP and MySQL.

And if you really want to get more into the back end of providing data to Ajax calls, consider Paul’s article Ajax It’s Good For What Rails You.



Did you love this article? Did you hate it? Think you can do better? Send us your Feedback. Feedback submitted here will be considered for publication on Webmonkey or Wired News, so if you don’t want us to print your comments, please say so in your email.