Every now and then a website that I work on has required a form where by the user needs to select multple entries from a SELECT input and submit them back to the server. The SELECT input which allows multiple selections is ugly and not especially user-friendly. As such, when developing version 8 of Transformers At The Moon, I wrote a JavaScript solution based on a input method proposed by my brother David Mapes.
The solution was to use a pair of SELECTs one as the original list and another as a "holder" which would be dynamically populated by clicking on an entry in the first list. We also wanted to the user to be able to remove items from the "holder" list and to be able to easily see how many entries there were in that list. To enable the solution a third input field was required. This time a HIDDEN field. This field keep track of each of the values which have been selected as a comma separated string. This means that when a FORM is submitted, it is the value of this HIDDEN field which is read, exploded and then used.
We decided that the first entry in each list would be a "header" and thus is ignored by the script. In the case of the "holder" SELECT, this OPTION is used to display the number of entries
Here is an example of the script in action. To use the script, simply click on a value in the first SELECT list and you will see that it is passed to the 2nd SELECT. Click on the element in the 2nd list to remove it from the selection.
After the working example you will find the code that is being used. PLEASE keep the headers intact so people know that you found it here.
Source Code
Here is the Javascript code. Please keep ALL of the headers intact if you use these functions.
<script type="text/javascript" language="javascript">
<!--
/**
* addOption()
* Takes the option from one SELECT list and adds it to another for user-friendly
* search selection. Updates a third field, a hidden field which the values in the
* second select list for easier POSTING
* @param string targetSelect
* @param string sourceSelect
* @param string hiddenField
* @return void
* @author Steven Mapes
* @copyright 2007 StevenMapes.com - Do not use without written permisson
**/
function addOption(targetSelect,sourceSelect,hiddenField) {
var z = document.getElementById(sourceSelect);
if (z.selectedIndex > 0 ) {
var display = z.options[z.selectedIndex].text;
var option = z.options[z.selectedIndex].value;
var y = document.createElement('option');
y.text = display;
y.value = option;
var x = document.getElementById(targetSelect);
try {
x.add(y,null);
}
catch(ex) {
x.add(y);
}
x.options[0].text = '* '+(x.length-1)+' selected *';
// Set hidden field
var h = document.getElementById(hiddenField);
h.value = h.value+option+',';
}
}
/**
* removeOption()
* Removed the selected option from a SELECT input as well as from an hidden
* field. I.E. Reverses addOption()
* @param string selectBox
* @param string hiddenField
* @return void
* @author Steven Mapes
* @copyright 2007 StevenMapes.com - Do not use without written permisson
**/
function removeOption(selectBox,hiddenField) {
try {
var x = document.getElementById(selectBox);
if (x.selectedIndex > 0 ) {
// Remove from hidden field
var h = document.getElementById(hiddenField);
h.value = h.value.replace(','+x.options[x.selectedIndex].value+',',',');
x.remove(x.selectedIndex);
x.options[0].text = '* '+(x.length-1)+' selected *';
x.selectedIndex = 0;
}
}
catch (err) {
// Do nothing
}
}
-->
</script>
Then create the HTML SELECT boxes. EG
<select name="select1" id="select1" onchange="addOption('targetSelect','select1','selected1')">
<option value="0" selected="selected">* Please select *</option>
<option value="1">Entry 1</option>
<option value="2">Entry 2</option>
<option value="3">Entry 3</option>
<option value="4">Entry 4</option>
<option value="5">Entry 5</option>
</select>
<select name="targetSelect" id="targetSelect" onchange="removeOption('targetSelect','selected1')">
<option value="0" selected="selected">* 0 selected *</option>
</select>
<input type="hidden" name="selected1" value="," id="selected1" />
If you have any questions, spot any bugs etc, then let me know
Eventually you will find lists of recent additions here as well as links to some of my other websites and other things of interest and/or importance