I have a HTML select dropdown with multiple
provided:
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
and assign a click handler which returns the currently clicked on elements' index:
document.getElementById("mySelect").onclick = function() {
alert(this.selectedIndex);
}
Which works fine when I select one of the elements only. But I want to return all indexes currently selected.
When I click Apple, Orange and Banana
a return like [0,1,3]
is what I want, but it does not work.
Working example: JSfiddle
I have a HTML select dropdown with multiple
provided:
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
and assign a click handler which returns the currently clicked on elements' index:
document.getElementById("mySelect").onclick = function() {
alert(this.selectedIndex);
}
Which works fine when I select one of the elements only. But I want to return all indexes currently selected.
When I click Apple, Orange and Banana
a return like [0,1,3]
is what I want, but it does not work.
Working example: JSfiddle
Share Improve this question asked Jun 17, 2019 at 11:45 supersizesupersize 14.9k19 gold badges85 silver badges144 bronze badges 7- @KévinBibollet the question is about the values not about the selectedIndex, isn't it? – supersize Commented Jun 17, 2019 at 11:49
- I think he needs indexes not the value, so is that duplicate? – Prashant Pimpale Commented Jun 17, 2019 at 11:50
- @DavidThomas please read carefully, it is about the index not the values. – supersize Commented Jun 17, 2019 at 11:50
- Yes, but you can use that logic in order to get the indexes. – Kévin Bibollet Commented Jun 17, 2019 at 11:51
-
you need to use
value="0"
,value="1"
,value="2"
– Prashant Pimpale Commented Jun 17, 2019 at 11:51
5 Answers
Reset to default 5There is a browser API for that selectedOptions but IE is not supported.
document.getElementById("mySelect").onclick = function() {
console.log(Array.from(this.selectedOptions).map(option => option.index))
}
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
One option:
// named function for reuse, not using Arrow syntax in
// order that we can retain, and use the 'this' within
// the function:
const retrieveSelectedIndices = function() {
// here we use the spread operator to
// expand the iterable this.options collection,
// allowing us to call Array.prototype.map()
// (Array.from(this.options) would be more or less
// identical:
const selected = [...this.options].map(
// we're not using 'this', so using Arrow
// function expression; here we use a ternary
// to return the index of the current <option>
// if it is selected, or Boolean false if not:
(opt, index) => opt.selected ? index : false
// we then call Array.prototype.filter() on
// the Array created by Array.prototype.map(),
// and here we test that i - the index retrieved
// previously - is not equal to false:
).filter(((i) => i !== false));
// we log the indices to the console(), but this is
// where you could work with the indices, for logging
// to an HTML <ul></ul> element, for example:
console.log(selected);
// and returning to the calling context, in the event
// this function will be used in an alternative manner:
return selected;
}
// using document.querySelector() to retrieve the first,
// and only, element matching the supplied CSS selector:
selectEl = document.querySelector('#mySelect');
// binding a function, the retrieveSelectedIndices()
// function, as the 'input' event-handler for on
// the <select id="mySelect"> element:
selectEl.addEventListener('input', retrieveSelectedIndices);
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
Please note that the above function does not maintain the order of selected/deselected elements.
Edited to use HTMLSelectElement.selectedOptions
in place of the HTMLSelectElement.options
, the existence of which I'd forgotten until the discussion in the ments. This reflects an update, rather than any attempt to gain credit for Daryll's sensible use of HTMLSelectElement.selectedOptions
.
That said, then, the above code could easily be modified to the following:
// named function for reuse, not using Arrow syntax in
// order that we can retain, and use the 'this' within
// the function:
const retrieveSelectedIndices = function() {
// here we use the spread operator to
// expand the iterable this.selectedOptions collection,
// a HTMLCollection of the currently-selected <option>
// elements, allowing us to call Array.prototype.map()
// (Array.from(this.selectedOptions) would be more or less
// identical:
const selected = [...this.selectedOptions].map(
// we're not using 'this', so using Arrow
// function expression; here we use a ternary
// to return the index of the current <option>
// if it is selected, or Boolean false if not:
(opt) => opt.index
)
// we log the indices to the console(), but this is
// where you could work with the indices, for logging
// to an HTML <ul></ul> element, for example:
console.log(selected);
// and returning to the calling context, in the event
// this function will be used in an alternative manner:
return selected;
}
// using document.querySelector() to retrieve the first,
// and only, element matching the supplied CSS selector:
selectEl = document.querySelector('#mySelect');
// binding a function, the retrieveSelectedIndices()
// function, as the 'input' event-handler for on
// the <select id="mySelect"> element:
selectEl.addEventListener('input', retrieveSelectedIndices);
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
References:
...
spread syntax.Array.prototype.filter()
.Array.prototype.map()
.- Arrow syntax.
- Conditional 'Ternary' operator.
HTMLSelectElement.options
.HTMLSelectElement.selectedOptions
.
Get all the options
. Add change event to your select
, get selected options, iterate over it to find the index of individual selected option.
const options = document.querySelectorAll('#mySelect > option');
let indexes = [];
document.querySelector('#mySelect').addEventListener('change', function() {
indexes = [];
const selectedOptions = this.selectedOptions;
[...selectedOptions].forEach((option) => {
const index = [...options].indexOf(option);
indexes.push(index) ;
})
console.log(indexes);
});
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
Try like this.
I have looped the options and checked for selected options and pushed it. and finally I joined the array and printed it.
var selectEl = document.querySelector('#mySelect');
var options = document.querySelectorAll('#mySelect option');
selectEl.addEventListener('click', function() {
var arr=[]
options.forEach(function(option, index) {
if(option.selected) { arr.push(index); }
})
console.log(arr.join(","));
})
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>
allTheOptions.forEach(function(items,i) {
if (items.selected) {
answer.push(i);
}
})
};
If the item is selected that push the index into array. Simple as that.
let allTheOptions = document.querySelectorAll('#mySelect option');
let select = document.querySelector('#mySelect');
select.addEventListener('change', function() {
let answer = [];
allTheOptions.forEach(function(items,i) {
if (items.selected) {
answer.push(i);
}
})
console.log(answer);
})
<select multiple id="mySelect">
<option>Apple</option>
<option>Orange</option>
<option>Pineapple</option>
<option>Banana</option>
</select>