How to get all selected values from <select multiple=multiple>?

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.


Solution 1:

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;
}

Solution 2:

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;

Solution 3:

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

Solution 4:

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