I need to alphabetize the options in a select list. I can’t just switch the innerHTML and value attributes because some options have classes and event listeners attached. Here is what I have so far:
function alphabetizeSelectListItems(theOldList) {
var theNewList;
var insertOptionHere;
theNewList = theOldList.cloneNode(true);
while(theOldList.options.length > 0) {
theOldList.options[0].remove();
}
while(theNewList.options.length > 0) {
insertOptionHere = null;
for(var optionCounter = 0; optionCounter < theOldList.length; optionCounter++) {
if(theNewList.options[0].innerHTML.toLocaleUpperCase().localeCompare(theOldList.options[optionCounter].innerHTML.toLocaleUpperCase()) < 0) {
insertOptionHere = optionCounter;
break;
}
}
if(insertOptionHere == null) {
theOldList.appendChild(theNewList.options[0]);
} else {
theOldList.insertBefore(theNewList.options[0], theOldList.options[insertOptionHere]);
}
}
theNewList.remove();
}
This clones the old list into a temp element, empties the options from the old list, and then copies each option from the temp list back into the old list in its alphabetical place. Then it deletes the temp list.
Problem with this is it copies everything except the event listeners. So I have to use the same select list with the same options but move them around. I’ve looked at bubble sorting examples and tried to adapt them to option elements instead of array elements, but when I swap two elements, I have to store one in a temporary element, and that removes the event listener.
Is this possible? Is there a way to swap around select list options while retaining the event listeners?
2
Answers
Event delegation is a programming paradigm that requires:
The element that is registered to an event should be an ancestor✼ of the element intended for interaction (eg. a
<button>
to "click", an<input>
to type into, etc).Write the event handler to conditionally accept only the elements intended for interaction. Exclude the rest by not including them.
✼An ancestor element contains children elements.
The advantages are as follows:
Any children elements of the registered ancestor can be delegated to the registered event(s). That also includes any elements added dynamically in the future.
There is no limit to the amount of elements that events can be delegated to.
These advantages give you almost full control of what does what, how, when, and why.
Details are commented in the example.
You can have an array of the elements and sort it. Then reintroduce the elements into the parent, using
appendChild
which will move them without cloning.From MDN:
If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position