|
|
|
|
|
|
|
Selected JavaScript Fun and Goodness
|
Once it has this name, it then attempts to find an <optgroup> with the same label in the target select, creating one if none is found. We're then ready to add the option. To make sure the new option is added in correct alphabetic order, we run through all the children of the target <optgroup> while the new option's text property precedes the existing option's text:
function addOption(sourceSelect, targetSelect, optionText, optionValue) { var newOpt = new Option(optionText, optionValue);
// Get optgroup label of the option being moved parentGroup = getGroupLabel(sourceSelect, optionText);
// Find matching optgroup in target select var newParentGroup = false; var optGrps = targetSelect.getElementsByTagName("optgroup") for (var index = 0; index < optGrps.length; index++) { if (optGrps[index].label == parentGroup) { newParentGroup = optGrps[index]; break; } } // if not found, create if (!newParentGroup) { blankOpt = new Option("", ""); blankOpt.style.visibility = 'hidden'; blankOpt.disabled = true; newParentGroup = document.createElement('optgroup'); newParentGroup.style.color = '#000099'; newParentGroup.label = parentGroup; targetSelect.appendChild(newParentGroup); targetSelect.appendChild(blankOpt); } // Add to target optgroup in alphabetic order cursorOpt = newParentGroup.firstChild; if (cursorOpt) do { if (cursorOpt.text > optionText) break; } while (cursorOpt = cursorOpt.nextSibling); if (cursorOpt) newParentGroup.insertBefore(newOpt, cursorOpt); else newParentGroup.appendChild(newOpt); // Fix for MSIE 6 if (IE6) { cursorOpt = newParentGroup.firstChild; while (cursorOpt) { if (cursorOpt.value == optionValue) cursorOpt.text = optionText; cursorOpt = cursorOpt.nextSibling; } } }
The getGroupLabel() function returns the name of the <optgroup> that contains the <option> with the label specified by the searchText parameter. We do this by looping through all <optgroup> elements of the select box, and iterating through all the options of each until we find an option with the text property we're looking for:
function getGroupLabel(selectBox, searchText) { // Find OptGroup of item being moved var parentGroup = false; var optGrps = selectBox.getElementsByTagName("optgroup") for (var index = 0; index < optGrps.length; index++) { for (var subIndex = 0; subIndex < optGrps[index].childNodes.length; subIndex++) if (optGrps[index].childNodes[subIndex].text == searchText) { parentGroup = optGrps[index].label; break; } } return parentGroup; }
deleteOption() just removes the <option> with the specified index. Safari in Windows won't let you remove an option just by setting it to null, so an alternative method is used for that browser:
function deleteOption(selectBox, theIndex) { var selLength = selectBox.length; if (selLength > 0) { if (WinSafari) { selectBox.options[theIndex].parentNode.removeChild(selectBox.options[theIndex]); } else { selectBox.options[theIndex] = null; } } }
We've now seen the four functions required for the manipulation of the two multiple select lists. In this case, as in most, one list holds the options that we want to store as the user's choices, the other holds the list of options that they have not selected. Once the user has chosen the options they desire, they need to submit the form containing the select boxes, so that we can save or otherwise process their particular choices. |
|
1 2 3 |
|
|
|
|
|
|