143
votes

Seemed odd I couldn't find this one already asked, but here it goes!

I have an html as follows:

<select id="select-meal-type" multiple="multiple">
    <option value="1">Breakfast</option>
    <option value="2">Lunch</option>
    <option value="3">Dinner</option>
    <option value="4">Snacks</option>
    <option value="5">Dessert</option>
</select>

How do I get all the values(an array?) that the user has selected in javascript?

For example, if the user has selected Lunch and Snacks, I want an array of { 2, 4 }.

This seems like it should be a very simple task but I can't seem to do it.

Thanks.

15

15 Answers

116
votes

The usual way:

var values = $('#select-meal-type').val();

From the docs:

In the case of <select multiple="multiple"> elements, the .val() method returns an array containing each selected option;

194
votes

Unless a question asks for JQuery the question should be first answered in standard javascript as many people do not use JQuery in their sites.

From RobG How to get all selected values of a multiple select box using JavaScript?:

  function getSelectValues(select) {
  var result = [];
  var options = select && select.options;
  var opt;

  for (var i=0, iLen=options.length; i<iLen; i++) {
    opt = options[i];

    if (opt.selected) {
      result.push(opt.value || opt.text);
    }
  }
  return result;
}
60
votes

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);
29
votes

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);
17
votes

You can use selectedOptions property

var options = document.getElementById('select-meal-type').selectedOptions;
var values = Array.from(options).map(({ value }) => value);
console.log(values);
<select id="select-meal-type" multiple="multiple">
    <option value="1">Breakfast</option>
    <option value="2" selected>Lunch</option>
    <option value="3">Dinner</option>
    <option value="4" selected>Snacks</option>
    <option value="5">Dessert</option>
</select>
15
votes

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
10
votes

$('#select-meal-type :selected') will contain an array of all of the selected items.

$('#select-meal-type option:selected').each(function() {
    alert($(this).val());
});

6
votes

Update October 2019

The following should work "stand-alone" on all modern browsers without any dependencies or transpilation.

<!-- display a pop-up with the selected values from the <select> element -->

<script>
 const showSelectedOptions = options => alert(
   [...options].filter(o => o.selected).map(o => o.value)
 )
</script>

<select multiple onchange="showSelectedOptions(this.options)">
  <option value='1'>one</option>
  <option value='2'>two</option>
  <option value='3'>three</option>
  <option value='4'>four</option>
</select>
5
votes

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.

4
votes

Try this:

$('#select-meal-type').change(function(){
    var arr = $(this).val()
});

Demo

$('#select-meal-type').change(function(){
  var arr = $(this).val();
  console.log(arr)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select-meal-type" multiple="multiple">
  <option value="1">Breakfast</option>
  <option value="2">Lunch</option>
  <option value="3">Dinner</option>
  <option value="4">Snacks</option>
  <option value="5">Dessert</option>
</select>

fiddle

3
votes

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
})
2
votes

Something like the following would be my choice:

let selectElement = document.getElementById('categorySelect');
let selectedOptions = selectedElement.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.

0
votes

Works everywhere without jquery:

var getSelectValues = function (select) {
    var ret = [];

    // fast but not universally supported
    if (select.selectedOptions != undefined) {
        for (var i=0; i < select.selectedOptions.length; i++) {
            ret.push(select.selectedOptions[i].value);
        }

    // compatible, but can be painfully slow
    } else {
        for (var i=0; i < select.options.length; i++) {
            if (select.options[i].selected) {
                ret.push(select.options[i].value);
            }
        }
    }
    return ret;
};
0
votes
$('#application_student_groups option:selected').toArray().map(item => item.value)
0
votes

If you have multiple select boxes with multiple='multiple' and you want to select all selected options from every dropdown then use this HTML:

<select id='Alphabets'>
    <option value="1">A</option>
    <option value="2">B</option>
    <option value="3">C</option>
</select>

<select id='Alphabets' multiple='multiple'>
    <option value="4">D</option>
    <option value="5">E</option>
    <option value="6">F</option>
</select>
<select id='Alphabets'>
    <option value="7">G</option>
    <option value="8">H</option>
    <option value="9">I</option>
</select>
<select id='Alphabets' multiple='multiple'>
    <option value="10">J</option>
    <option value="11">K</option>
    <option value="12">L</option>
</select>

JavaScript for above UI:

function show_Alphebets()
{
        var tag =document.querySelectorAll("select");        
        var values="";
        for(var i=1; i<4; i++) {
            if(tag[i].options.length>0)
            for (var option of tag[i].selectedOptions) {                  
                  values+= i+"(multiple)="+option.value+",";
            }
            else values+= i+"="+tag[i].value+",";
        }
        alert(values);
}