How to get all selected values of a multiple select box?
Thank you for this answer. Could you please step through it for me? I think I understand MOST of it, but what does var options = select && select.options; do? In my inexperience, I expected that to be var options = select.options;
@TecBrat var options = select && select.options ensures that select is not undefined, before accessing its attributes.
I don’t think the line with && makes much sense . if select is not defined getElementById will return null . In this case, options will be null and error once you try to access to length property. But maybe I’m missing something?
With jQuery, the usual way:
var values = $('#select-meal-type').val();
In the case of elements, the .val() method returns an array containing each selected option;
This is perfect. Is there also a way to retrieve the labels or text instead of the values themselves?
Actually, I found the best, most-succinct, fastest, and most-compatible way using pure JavaScript (assuming you don’t need to fully support IE lte 8) is the following:
var values = Array.prototype.slice.call(document.querySelectorAll('#select-meal-type option:checked'),0).map(function(v,i,a) < return v.value; >);
UPDATE (2017-02-14):
An even more succinct way using ES6/ES2015 (for the browsers that support it):
const selected = document.querySelectorAll('#select-meal-type option:checked'); const values = Array.from(selected).map(el => el.value);
Alternatively, if you have the element: Array.from(element.querySelectorAll(«option:checked»),e=>e.value);
Thanks @AdamLeggett. For reference to those who don’t know, that would change make @Someguynamedpie’s code above to: Array.from(element.selectedOptions).map(v=>v.value); .
It would, but see my answer below — it doesn’t work at all on IE and has odd behavior in some older versions of Chrome and Firefox. If you don’t care about performance, querySelectorAll or filtering element.options does get the job done. Also, you can do [].map.call() instead of using Array.from(), I don’t know what impact this would have on performance but it certainly wouldn’t be negative.
used checked This worked for me, on a multi select dropdown, but should work for all drop-downs as well $(«.multiple_select > option:checked»).each(function()< console.log(this.value) >);
You can use selectedOptions property
var options = document.getElementById('select-meal-type').selectedOptions; var values = Array.from(options).map((< value >) => value); console.log(values);
this is a fantastic answer super simple and concise and can even be reduced to a single line let selectedOptions = Array.from(document.getElementById(selectElem).selectedOptions).map((< value >) => value);
In 2023 this should be the accepted answer. Much cleaner and cross-compatible. Does not require jQuery or other convoluted steps.
[. select.options].filter(option => option.selected).map(option => option.value)
Where select is a reference to the element.
- [. select.options] takes the Array-like list of options and destructures it so that we can use Array.prototype methods on it (Edit: also consider using Array.from() )
- filter(. ) reduces the options to only the ones that are selected
- map(. ) converts the raw elements into their respective values
This code looks much nicer than the ugly for loop over options.length . But is [. select.options] efficient in modern JS? Doesn’t this iterate over whole collection three times? (i.e. first to build an array from options, second to filter, third to map) where you could do it in one go with ugly for loop
@Anentropic it’s a good question but I don’t think efficiency matters much unless we’re talking about hundreds or thousands of options.
If you wanna go the modern way, you can do this:
const selectedOpts = [. field.options].filter(x => x.selected);
The . operator maps iterable ( HTMLOptionsCollection ) to the array.
If you’re just interested in the values, you can add a map() call:
const selectedValues = [. field.options] .filter(x => x.selected) .map(x => x.value);
Check-it Out:
$("#aSelect").click(function()< var selectedValues = []; $("#lstSelect :selected").each(function()< selectedValues.push($(this).val()); >); alert(selectedValues); return false; >);
Not a fan — the «HTML» isn’t HTML (readable, but not HTML), and the answer requires adding JQuery as a dependency.
First, use Array.from to convert the HTMLCollection object to an array.
let selectElement = document.getElementById('categorySelect') let selectedValues = Array.from(selectElement.selectedOptions) .map(option => option.value) // make sure you know what '.map' does // you could also do: selectElement.options
suppose the multiSelect is the Multiple-Select-Element, just use its selectedOptions Property:
//show all selected options in the console: for ( var i = 0; i
$(‘#select-meal-type :selected’) will contain an array of all of the selected items.
$('#select-meal-type option:selected').each(function() < alert($(this).val()); >);
Pretty much the same as already suggested but a bit different. About as much code as jQuery in Vanilla JS:
selected = Array.prototype.filter.apply( select.options, [ function(o) < return o.selected; >] );
It seems to be faster than a loop in IE, FF and Safari. I find it interesting that it’s slower in Chrome and Opera.
Another approach would be using selectors:
selected = Array.prototype.map.apply( select.querySelectorAll('option[selected="selected"]'), [function (o) < return o.value; >] );
That’s a drawback of bare JS compared to using libraries. The selectedOptions property lacks in reliable browser support. Library like jQuery will hide that from you. A lot has changed since 2013 but a quick google shows that people still have issues with selectedOptions.
Update October 2019
The following should work «stand-alone» on all modern browsers without any dependencies or transpilation.
element -->
If you need to respond to changes, you can try this:
document.getElementById('select-meal-type').addEventListener('change', function(e) < let values = [].slice.call(e.target.selectedOptions).map(a =>a.value)); >)
The [].slice.call(e.target.selectedOptions) is needed because e.target.selectedOptions returns a HTMLCollection , not an Array . That call converts it to Array so that we can then apply the map function, which extract the values.
Sadly this won’t work everywhere, turns out IE11 does not have the field selectedOptions. The following does work however: Array.prototype.slice.call(field.querySelectorAll(‘:checked’))
Array.from(document.getElementById("test").options).filter(option => option.selected).map(option => option.value);
if you want as you expressed with breaks after each value;
$('#select-meal-type').change(function()< var meals = $(this).val(); var selectedmeals = meals.join(", "); // there is a break after comma alert (selectedmeals); // just for testing what will be printed >)
$('#select-meal-type').change(function()< var arr = $(this).val() >);
$('#select-meal-type').change(function()< var arr = $(this).val(); console.log(arr) >)
Here is an ES6 implementation:
value = Array(. el.options).reduce((acc, option) => < if (option.selected === true) < acc.push(option.value); >return acc; >, []);
This works great. It’s interesting to note that because element.options is a live collection, it cannot be reduced. It must first be converted to an Array as seen in the above answer.
Building on Rick Viscomi’s answer, try using the HTML Select Element’s selectedOptions property:
let txtSelectedValuesObj = document.getElementById('txtSelectedValues'); [. txtSelectedValuesObj.selectedOptions].map(option => option.value);
- selectedOptions returns a list of selected items.
- Specifically, it returns a read-only HTMLCollection containing HTMLOptionElements.
- . is spread syntax. It expands the HTMLCollection ‘s elements.
- [. ] creates a mutable Array object from these elements, giving you an array of HTMLOptionElements .
- map() replaces each HTMLObjectElement in the array (here called option ) with its value ( option.value ).
Dense, but it seems to work.
Watch out, selectedOptions isn’t supported by IE!
You can get as an array the values from the at the submit of the form as this example :
const form = document.getElementById('form-upload'); form.addEventListener('change', (e) => < const formData = new FormData(form); const selectValue = formData.getAll('pets'); console.log(selectValue); >)
Something like the following would be my choice:
let selectElement = document.getElementById('categorySelect'); let selectedOptions = selectElement.selectedOptions || [].filter.call(selectedElement.options, option => option.selected); let selectedValues = [].map.call(selectedOptions, option => option.value);
It’s short, it’s fast on modern browsers, and we don’t care whether it’s fast or not on 1% market share browsers.
Note, selectedOptions has wonky behavior on some browsers from around 5 years ago, so a user agent sniff isn’t totally out of line here.
How to get multiple values from an HTML element
If you want to put multiple values in an element, do something like value=»**value1**» value2=»**value2**» . You can’t add a value without an attribute name. Anyway, what to you want to do with the two variables in the end?
no no I was just asking is there a way for doing like that, I know the syntax of HTML is not valid but my concept is to take values from one option
Then, maybe something like this value=»**value1**/**value2**» could be turned into multiple option elements using some JS.
3 Answers 3
You could make your own attribute. I know you probably do not want to get the element with an ID, but I don’t know the context. You can just call getAttribute on the option and use any name you gave to the «custom» attribute.
window.addEventListener('load', ()=> < const option = document.getElementById('option'); function init() < //Use this to get the values console.log(option.getAttribute('other-value')); >init(); >);
I don’t know what you really want to do with your piece of code,
but here is a proper way to use the option elements, and a way to split multiple values with a fixed separator:
var example = document.getElementById('example'); example.addEventListener('change', function() < // Console displays the “value”, and not the text, of the selected option console.log("option value:", example.value); >); // Here is what I'll do with your "multiple" values var country = document.getElementById('country'); var options = country.querySelector('option'); var values = options.value.split("/"); values.forEach(function(val) < country.innerHTML += ""; >);
My simple example
Example with option getting splitted
Javascript Get Values from Multiple Select Option Box
This one is driving me nuts. It’s got to be something simple and stupid that I am overlooking. I have a multiple select box in a form. I am just trying to get the values that are selected. In my loop, if I use alert then I have no problem. As soon as try to concatenate the values I get the error ‘SelBranch[. ].selected’ is null or not an object
4 Answers 4
The for loop is getting one extra run. Change
Here i am posting the answer just for reference which may become useful.
var elem = document.querySelector("select"); console.log(elem.selectedOptions); //=> HTMLCollection [, ]
This would also work on non- multiple elements
Warning: Support for this selectedOptions seems pretty unknown at this point