A
ListBox
is rendered as
a <select>
element[
^]. That element submits the selected items in the order they were declared in the source,
not the order in which the user selects them.
If you need to know the order in which the user selected the items, then you will need to use JavaScript. You will need to monitor the list's
change
event; get the list of selected options; compare it to the previously selected options to find out which option has just been selected; then store that list in a hidden field. You can then use the hidden field on the server to retrieve the ordered list.
For example:
document.addEventListener("DOMContentLoaded", () => {
"use strict";
const options = document.getElementById("options");
const orderedOptions = document.getElementById("orderedOptions");
const getAllSelectedOptions = () => [...options.options].filter(o => o.selected).map(o => o.value);
const getAndValidateInitialSelectedOptions = () => {
const initialValue = orderedOptions.value.split(",");
const selectedOptions = getAllSelectedOptions();
if (initialValue.some(x => !selectedOptions.includes(x))) {
console.debug("Selected options does not match ordered options", initialValue, selectedOptions);
return selectedOptions;
}
if (selectedOptions.some(x => !initialValue.includes(x))) {
console.debug("Selected options does not match ordered options", initialValue, selectedOptions);
return selectedOptions;
}
return initialValue;
};
let selectedOptions = getAndValidateInitialSelectedOptions();
console.debug("Initial selected values", selectedOptions);
options.addEventListener("change", () => {
const allSelectedOptions = getAllSelectedOptions();
selectedOptions = selectedOptions.filter(x => allSelectedOptions.includes(x));
allSelectedOptions.forEach(value => {
if (!selectedOptions.includes(value)) {
selectedOptions.push(value);
}
});
orderedOptions.value = selectedOptions.join(",");
});
});
Demo[
^]