8.13 Changing select Element Content
NN 4, IE 4
8.13.1 Problem
You want to change the
options in a select element in response to other
form control settings.
8.13.2 Solution
Begin by removing all option elements from the
desired select element:
document.myForm.mySelect.options.length = 0;
Then repopulate the option elements with new
option objects:
document.myForm.mySelect.options[0] = new Option("Extra Fine", "xf", false, false);
document.myForm.mySelect.options[1] = new Option("Fine", "f", false, false);
document.myForm.mySelect.options[2] = new Option("Medium", "m", false, false);
This syntax works for all browsers from IE 4 and NN 4 onward, but
Navigator 4 does not resize the width of the
select element to fit new, wider option text, and
generally requires a call to history.go(0) to
force the revised options to appear.
8.13.3 Discussion
The constructor function syntax for the option
object is as follows:
var newOpt = new Option("text", "value", isDefaultSelectedFlag, isSelectedFlag);
The text parameter is a string containing
the item's label as seen by the user in the
select list, while the
value parameter is the otherwise hidden
string that is submitted with the form if the option is selected. The
two Boolean parameters let you set whether the option is the default
selected option (i.e., the equivalent of having the
selected attribute set in the HTML for the
option element), and whether the option is
currently selected.
You can replace individual options by assigning a new
option object to one of the elements in the
options array. But if you need to change multiple
items, it's cleaner to remove all of the old ones
and start the list fresh.
Data for the new option elements can come from
sources such as JavaScript custom objects embedded within the
page's script. This means that you have to include
all possible data choices within the page's scripts.
You'll also have to devise a data structure that
works for the kind of data you want to convey via the
select element. For example, consider a page that
displays two select elements, from which users
select the nearest city around the world to which to submit a form.
The first select element lists regions of the
world. With the choice of each region, the second
select element lists the cities belonging only to
that region. The HTML for the two select elements
is as follows:
Submit Request to: <select name="continent" onchange="setCities(this)">
<option value="" selected>Choose a Region:</option>
<option value="africa">Africa</option>
<option value="asia">Asia</option>
<option value="australia">Australia/Pacific</option>
<option value="europe">Europe</option>
<option value="noamer">North America</option>
<option value="soamer">South America</option>
</select>
<select name="city">
<option value="" selected>Choose a City:</option>
</select>
A custom object contains all of the data required for the
setCities( ) event handler function to modify the
contents of the second select element. Here is the
data structure for the data, delivered as a custom JavaScript object:
var regiondb = new Object( )
regiondb["africa"] = [{value:"102", text:"Cairo"},
{value:"88", text:"Lagos"},
{value:"80", text:"Nairobi"},
{value:"55", text:"Pretoria"}];
regiondb["asia"] = [{value:"30", text:"Ankara"},
{value:"21", text:"Bangkok"},
{value:"49", text:"Beijing"},
{value:"76", text:"New Delhi"},
{value:"14", text:"Tokyo"}];
regiondb["australia"] = [{value:"64", text:"Suva"},
{value:"12", text:"Sydney"}];
regiondb["europe"] = [{value:"11", text:"Athens"},
{value:"35", text:"Frankfurt"},
{value:"3", text:"London"},
{value:"15", text:"Madrid"},
{value:"1", text:"Paris"},
{value:"10", text:"Rome"},
{value:"6", text:"Stockholm"},
{value:"97", text:"St. Petersburg"}];
regiondb["noamer"] = [{value:"73", text:"Dallas"},
{value:"71", text:"Los Angeles"},
{value:"5", text:"New York"},
{value:"37", text:"Toronto"}];
regiondb["soamer"] = [{value:"65", text:"Buenos Aires"},
{value:"31", text:"Caracas"},
{value:"66", text:"Rio di Janeiro"}];
Each time the user makes a new selection from the first
select element, the onchange
event handler triggers the following function that repopulates the
second select element:
function setCities(chooser) {
var cityChooser = chooser.form.elements["city"];
// empty previous settings
cityChooser.options.length = 0;
// get chosen value to act as index to regiondb hash table
var choice = chooser.options[chooser.selectedIndex].value;
var db = regiondb[choice];
// insert default first item
cityChooser.options[0] = new Option("Choose a City:", "", true, false);
if (choice != "") {
// loop through array of the hash table entry, and populate options
for (var i = 0; i < db.length; i++) {
cityChooser.options[i + 1] = new Option(db[i].text, db[i].value);
}
}
}
As a data source alternative, if you are using IE 5 and later for
Windows or Netscape 6 and later, you can reach out to the server to
load XML data into a virtual XML document (see Recipe 14.4), and
parse the data in the XML document tree to obtain values for the
Option( ) constructor function parameters.
In place of the DOM Level 0 syntax shown thus far, you may instead
use the W3C DOM style of node tree modification syntax. You are free
to use it for option element modification, but an
inconsistency in the implementations between IE (through Version 6)
and the W3C DOM (as implemented in NN 6 and later) complicates the
matter. The W3C DOM provides two methods of the
select element, add( )
and remove( ), that slightly simplify the usual
node tree modification sequence for this element. The following
function is a W3C DOM version of the setCities(
)
function shown earlier. It accounts for the browser differences in
the second parameter of the add( ) method:
function setCities(chooser) {
var newElem;
var where = (navigator.appName = = "Microsoft Internet Explorer") ? -1 : null;
var cityChooser = chooser.form.elements["city"];
while (cityChooser.options.length) {
cityChooser.remove(0);
}
var choice = chooser.options[chooser.selectedIndex].value;
var db = regiondb[choice];
newElem = document.createElement("option");
newElem.text = "Choose a City:";
newElem.value = "";
cityChooser.add(newElem, where);
if (choice != "") {
for (var i = 0; i < db.length; i++) {
newElem = document.createElement("option");
newElem.text = db[i].text;
newElem.value = db[i].value;
cityChooser.add(newElem, where);
}
}
}
The second parameter of the add( ) method
determines the location of the added option
element. The W3C DOM expects either a reference to an existing
option element or null. The
latter signifies that the added element goes to the end of the list.
IE's second parameter is optional, but when
supplied, it is supposed to be an integer pointing to the zero-based
index of the options array where the added element is to go. If you
omit the second parameter or supply a -1, the new
option goes to the end of the list. That is the reason for the brief
browser sniffing near the beginning of the function to set the second
parameter value.
8.13.4 See Also
Recipe 3.8 for creating custom object data structures.
|