如何获取多个选择框的所有选定值?

我有一个带有 multiple属性的 <select>元素。如何使用 JavaScript 获取该元素的选定值?

我是这么想的:

function loopSelected() {
var txtSelectedValuesObj = document.getElementById('txtSelectedValues');
var selectedArray = new Array();
var selObj = document.getElementById('slct');
var i;
var count = 0;
for (i=0; i<selObj.options.length; i++) {
if (selObj.options[i].selected) {
selectedArray[count] = selObj.options[i].value;
count++;
}
}
txtSelectedValuesObj.value = selectedArray;
}
339329 次浏览

Check-it Out:

HTML:

<a id="aSelect" href="#">Select</a>
<br />
<asp:ListBox ID="lstSelect" runat="server"  SelectionMode="Multiple" Width="100px">
<asp:ListItem Text="Raj" Value="1"></asp:ListItem>
<asp:ListItem Text="Karan" Value="2"></asp:ListItem>
<asp:ListItem Text="Riya" Value="3"></asp:ListItem>
<asp:ListItem Text="Aman" Value="4"></asp:ListItem>
<asp:ListItem Text="Tom" Value="5"></asp:ListItem>
</asp:ListBox>

JQUERY:

$("#aSelect").click(function(){
var selectedValues = [];
$("#lstSelect :selected").each(function(){
selectedValues.push($(this).val());
});
alert(selectedValues);
return false;
});

CLICK HERE TO SEE THE DEMO

No jQuery:

// Return an array of the selected opion values
// select is an HTML select element
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;
}

Quick example:

<select multiple>
<option>opt 1 text
<option value="opt 2 value">opt 2 text
</select>
<button onclick="
var el = document.getElementsByTagName('select')[0];
alert(getSelectValues(el));
">Show selected values</button>

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

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

With jQuery, 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;

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

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

Same as the earlier answer but using underscore.js.

function getSelectValues(select) {
return _.map(_.filter(select.options, function(opt) {
return opt.selected; }), function(opt) {
return opt.value || opt.text; });
}

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

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

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 < multiSelect.selectedOptions.length; i++) {
console.log( multiSelect.selectedOptions[i].value);
}

You Can try this script

     <!DOCTYPE html>
<html>
<script>
function getMultipleSelectedValue()
{
var x=document.getElementById("alpha");
for (var i = 0; i < x.options.length; i++) {
if(x.options[i].selected ==true){
alert(x.options[i].value);
}
}
}
</script>
</head>
<body>
<select multiple="multiple" id="alpha">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
<option value="d">D</option>
</select>
<input type="button" value="Submit" onclick="getMultipleSelectedValue()"/>
</body>
</html>

You can use [].reduce for a more compact implementation of RobG's approach:

var getSelectedValues =  function(selectElement) {
return [].reduce.call(selectElement.options, function(result, option) {
if (option.selected) result.push(option.value);
return result;
}, []);
};

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.

ES6

[...select.options].filter(option => option.selected).map(option => option.value)

Where select is a reference to the <select> element.

To break it down:

  • [...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 <option> elements into their respective values

My template helper looks like this:

 'submit #update': function(event) {
event.preventDefault();
var obj_opts = event.target.tags.selectedOptions; //returns HTMLCollection
var array_opts = Object.values(obj_opts);  //convert to array
var stray = array_opts.map((o)=> o.text ); //to filter your bits: text, value or selected
//do stuff
}

Here is an ES6 implementation:

value = Array(...el.options).reduce((acc, option) => {
if (option.selected === true) {
acc.push(option.value);
}
return acc;
}, []);

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

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

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

In detail,

  • 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!

Check this:

HTML:

<select id="test" multiple>
<option value="red" selected>Red</option>
<option value="rock" selected>Rock</option>
<option value="sun">Sun</option>
</select>

Javascript one line code

Array.from(document.getElementById("test").options).filter(option => option.selected).map(option => option.value);

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.

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

Here ya go.

const arr = Array.from(el.features.selectedOptions) //get array from selectedOptions property
const list = []
arr.forEach(item => list.push(item.value)) //push each item to empty array
console.log(list)

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>

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>

$('#application_student_groups option:selected').toArray().map(item => item.value)

You can create your own function like this and use it everywhere

Pure JS

/**
* Get values from multiple select input field
* @param {string} selectId - the HTML select id of the select field
**/
function getMultiSelectValues(selectId) {
// get the options of select field which will be HTMLCollection
// remember HtmlCollection and not an array. You can always enhance the code by
// verifying if the provided select is valid or not
var options = document.getElementById(selectId).options;
var values = [];
    

// since options are HtmlCollection, we convert it into array to use map function on it
Array.from(options).map(function(option) {
option.selected ? values.push(option.value) : null
})


return values;
}

you can get the same result using jQuery in a single line

$('#select_field_id').val()

and this will return the array of values of well.

You can get as an array the values from the <select> 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);
})
<form id="form-upload">
<select name="pets" multiple id="pet-select">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
<option value="spider">Spider</option>
<option value="goldfish">Goldfish</option>
</select>
</form>