Как получить все выбранные значения из <select multiple = multiple>?

116

Казалось странным, я не смог найти этот вопрос, но вот он!

У меня есть следующий HTML-код:

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

Как получить все значения (массив?), Выбранные пользователем в javascript?

Например, если пользователь выбрал «Обед и закуски», мне нужен массив из {2, 4}.

Кажется, это должна быть очень простая задача, но я не могу этого сделать.

Спасибо.

Кайл
источник

Ответы:

105

Обычный способ:

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

Из документов :

В случае <select multiple="multiple">элементов .val()метод возвращает массив, содержащий каждую выбранную опцию;

Феликс Клинг
источник
10
@augurone: Я утверждаю, что это так?
Феликс Клинг,
9
@FelixKling, ты просто ввел в заблуждение кого-то, кто может сразу включить всю библиотеку jQuery только для этого, прежде чем он поймет, что не должен, если ему действительно не нужно.
Амир Африди,
32
@AamirAfridi: вопрос помечен jQuery. Пометка вопроса библиотекой обычно означает, что оператор использует эту библиотеку и что ответы с использованием библиотеки приветствуются. Могу ли я также предложить альтернативный способ Ina перейти к jQuery сегодня? Может быть. Но этому вопросу больше 3-х лет. Также см. Комментарий OP к другому ответу: stackoverflow.com/questions/11821261/…
Феликс Клинг,
12
Ты прав. Это имеет смысл, если вопрос помечен тегом jQuery 😐
Амир Африди
148

Если вопрос не касается JQuery, то сначала нужно ответить на этот вопрос в стандартном javascript, поскольку многие люди не используют JQuery на своих сайтах.

From RobG Как получить все выбранные значения из окна множественного выбора с помощью 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;
}
lvoelk
источник
24
Он помечен jquery.
Кайл
1
ха, не видел этого: / все еще +1
mw_21 01
6
О чем selectedOptions? Разве недостаточно кроссбраузерности? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbits 08
Обратите внимание, что если valueатрибута нет , то opt.value= opt.text.
thdoan
1
В заключение! Ваниль ... мой любимый аромат
папиро
46

На самом деле, я нашел лучший, самый краткий, быстрый и наиболее совместимый способ использования чистого JavaScript (при условии, что вам не нужно полностью поддерживать IE lte 8):

var values = Array.prototype.slice.call(document.querySelectorAll('#select-meal-type option:checked'),0).map(function(v,i,a) { 
    return v.value; 
});

ОБНОВЛЕНИЕ (2017-02-14):

Еще более лаконичный способ использования ES6 / ES2015 (для браузеров, которые его поддерживают):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
КайлФаррис
источник
7
В качестве альтернативы, если у вас есть элемент:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie
1
К вашему сведению, быстрее использовать коллекцию selectedOptions / options, чем использовать querySelectorAll.
Адам Леггетт
4
Спасибо @AdamLeggett. Для ссылки на тех , кто не знает, что бы изменить макияж @ код Someguynamedpie в выше: Array.from(element.selectedOptions).map(v=>v.value);.
KyleFarris
Было бы, но посмотрите мой ответ ниже - он вообще не работает в IE и имеет странное поведение в некоторых старых версиях Chrome и Firefox. Если вас не волнует производительность, querySelectorAll или filtering element.options справятся со своей задачей. Кроме того, вы можете использовать [] .map.call () вместо использования Array.from (), я не знаю, какое влияние это окажет на производительность, но это определенно не будет отрицательным.
Адам Леггетт
used checked Это сработало для меня в раскрывающемся $(".multiple_select > option:checked").each(function(){ console.log(this.value) });
списке
15

Если вы хотите идти современным путем, вы можете сделать это:

const selectedOpts = [...field.options].filter((x) => x.selected);

...Оператор переводит Iterable ( HTMLOptionsCollection) в массив.

Если вас просто интересуют значения, вы можете добавить map()вызов:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);
Томаш Зато - Восстановить Монику
источник
Этот ответ заслуживает большего уважения. Отличное решение, спасибо!
Silver Ringvee
10

Сначала используйте Array.fromдля преобразования HTMLCollectionобъекта в массив.

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
Hassan
источник
9

$('#select-meal-type :selected') будет содержать массив всех выбранных элементов.

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

Взаимодействие с другими людьми

Джон Конде
источник
6

Обновление октябрь 2019 г.

Следующее должно работать автономно во всех современных браузерах без каких-либо зависимостей или транспиляции.

<!-- 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>
Fergie
источник
4

Попробуй это:

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

Демо

$('#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>

скрипка

неопределенный
источник
3

если хотите, как вы выразились с перерывами после каждого значения;

$('#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
})
ewroman
источник
2

Если вам нужно отреагировать на изменения, вы можете попробовать следующее:

document.getElementById('select-meal-type').addEventListener('change', function(e) {
    let values = [].slice.call(e.target.selectedOptions).map(a => a.value));
})

[].slice.call(e.target.selectedOptions)Необходимо потому , что e.target.selectedOptionsвозвращает HTMLCollection, а не Array. Этот вызов преобразует его в, Arrayчтобы затем мы могли применить mapфункцию, которая извлекает значения.

adlr0
источник
1
К сожалению, это не сработает везде, оказывается, в IE11 нет поля selectedOptions. Однако следующее действительно работает:Array.prototype.slice.call(field.querySelectorAll(':checked'))
JamesDev
0

Я бы выбрал что-то вроде следующего:

let selectElement = document.getElementById('categorySelect');
let selectedOptions = selectedElement.selectedOptions || [].filter.call(selectedElement.options, option => option.selected);
let selectedValues = [].map.call(selectedOptions, option => option.value);

Короче говоря, это быстро в современных браузерах, и нам все равно, быстро он или нет в браузерах с долей рынка 1%.

Обратите внимание, что selectedOptions ведет себя нестабильно в некоторых браузерах примерно 5 лет назад, поэтому нюхание пользовательского агента здесь не совсем неприемлемо.

Адам Леггетт
источник
0

Ты можешь использовать selectedOptions

var selectedValues = Array.from(document.getElementById('select-meal-type').selectedOptions).map(el=>el.value);
console.log(selectedValues);
<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>

Тан Чанрит
источник
-1

Работает везде без 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;
};
Пол Каддихи
источник
selectedOptiongsне поддерживается в IE
Dustin Poissant