|
|
|
|
|
|
|
Selected JavaScript Fun and Goodness
|
|
Here's a sample of JS code for allowing users to choose multiple items from a list of available options. There are many examples of code like this, however this example has the enhancement of keeping the lists well organised. To do this, we need to find the parent OPTGROUP that contains a selected OPTION, and we also need to insert a new OPTION in a specific OPTGROUP of a SELECT list. |
compton, 23 November 07
Updated 2 September 08
|
There are several occasions where users need an ability to make a list by taking items from a 'master' list of available items. This type of mechanism is a very usable way to allow users to choose featured articles for display next to another article.
The JS code below extends the usual functionality so that the two lists are kept maintained in group and alphabetic order, enhancing usability when there are lots of items in either list (or both). There are five functions needed for full functionality, all of which are shown here in their entirety. There's also a quick and dirty test function provided out of interest.
To use the code, your page needs a HTML form containing two multiple select lists, and two buttons (plus of course the normal submit button and any other fields you may wish). One select list is for the user's currently chosen items, while the other is populated with the unselected items.
The first button is for adding items from the available items list to the current items list, and the other is for the reverse procedure (both do this by calling moveOptions() passing in the ids of the source and target select lists).
The items in both lists should be grouped within OPTGROUP elements. The JS code here will place a moved item within a matching OPTGROUP in the target list, creating the OPTGROUP if it does not already exist in the target list. Items within an OPTGROUP are maintained in alphabetic order (and so should be initially sorted thus when the select lists are populated).
A couple of variables are set to indicate the browser being used:
var NS4 = (navigator.appName == "Netscape" && parseInt(navigator.appVersion) < 5); var IE6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) <= 5); var WinSafari = (navigator.userAgent.indexOf("Safari") >= 0) && (navigator.userAgent.indexOf("Windows") >= 0)
Next up is the moveOptions() function. It simply iterates through the options in the sourceSelect list, building two arrays which hold the names and values of all the selected options. It also stores the selected indexes in a third array called wewilldie, for reasons which should become clear later.
Once it has these arrays, it can run through adding all selected items to the targetSelect list. Note that it runs through in reverse order, which you'll see is necessary when we look at the addOption() function. Once the options have been recreated in the targetSelect list, we run through again, this time in forwards order, removing the options from the source select.
function moveOptions(sourceSelect, targetSelect) { var selLength = sourceSelect.length; var selectedText = new Array(); var wewilldie = new Array(); var selectedValues = new Array(); var selectedCount = 0; var index; for(index=selLength-1; index>=0; index--) { if(sourceSelect.options[index].selected && sourceSelect.options[index].text != '') { selectedText[selectedCount] = sourceSelect.options[index].text; selectedValues[selectedCount] = sourceSelect.options[index].value; wewilldie[selectedCount] = index; selectedCount++; } } for(index=selectedCount-1; index>=0; index--) addOption(sourceSelect, targetSelect, selectedText[index], selectedValues[index]);
for(index=0; index<selectedCount; index++) deleteOption(sourceSelect, wewilldie[index]);
if(NS4) history.go(0); }
The addOption() function needs to add the new option within an <optgroup> element in targetSelect having the same name as in sourceSelect. It calls the getGroupLabel() function, defined next, to get the name of the containing <optgroup> (ie its label property). |
|
1 2 3 |
|
|
|
|
|
|