Jak pobrać wszystkie wybrane wartości z <select multiple = multiple>?

115

Wydawało się dziwne, że nie mogłem już znaleźć tego, o który pytano, ale gotowe!

Mam następujący 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>

Jak uzyskać wszystkie wartości (tablicę?), Które użytkownik wybrał w javascript?

Na przykład, jeśli użytkownik wybrał Lunch i przekąski, chcę mieć tablicę {2, 4}.

Wydaje się, że powinno to być bardzo proste zadanie, ale nie mogę tego zrobić.

Dzięki.

Kyle
źródło

Odpowiedzi:

105

Zwykły sposób:

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

Z dokumentów :

W przypadku <select multiple="multiple">elementów .val()metoda zwraca tablicę zawierającą każdą wybraną opcję;

Felix Kling
źródło
10
@augurone: Czy twierdzę, że tak jest?
Felix Kling
9
@FelixKling właśnie zmyliłeś kogoś, kto może od razu dołączyć całą bibliotekę jQuery tylko w tym celu, zanim zda sobie sprawę, że nie powinien, chyba że naprawdę tego potrzebuje.
Aamir Afridi,
32
@AamirAfridi: pytanie jest oznaczone tagiem jQuery. Oznaczanie pytania biblioteką zwykle oznacza, że ​​operator korzysta z tej biblioteki, a odpowiedzi korzystające z biblioteki są mile widziane. Czy mógłbym również zasugerować dzisiaj alternatywny sposób wejścia do jQuery? Może. Ale to pytanie ma więcej niż 3 lata. Zobacz także komentarz OP na temat innej odpowiedzi: stackoverflow.com/questions/11821261/…
Felix Kling
12
Masz rację. To ma sens, jeśli pytanie jest oznaczone tagiem jQuery 😐
Aamir Afridi
148

O ile pytanie nie dotyczy JQuery, najpierw należy odpowiedzieć na to pytanie w standardowym javascript, ponieważ wiele osób nie używa JQuery w swoich witrynach.

Od RobG Jak uzyskać wszystkie wybrane wartości z pola wielokrotnego wyboru za pomocą 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
źródło
24
Jest oznaczony tagiem jquery.
Kyle
1
ha, tego nie widziałem: / nadal +1
mw_21
6
O co chodzi selectedOptions? Czy to nie wystarczy dla wielu przeglądarek? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbit
Zauważ, że gdy nie ma valueatrybutu, wtedy opt.value= opt.text.
thdoan
1
Wreszcie! Wanilia ... mój ulubiony smak
papiro
46

Właściwie znalazłem najlepszy, najbardziej zwięzły, najszybszy i najbardziej kompatybilny sposób korzystania z czystego JavaScript (zakładając, że nie musisz w pełni obsługiwać IE lte 8) jest następujący:

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

AKTUALIZACJA (14.02.2017):

Jeszcze bardziej zwięzły sposób korzystania z ES6 / ES2015 (dla przeglądarek, które go obsługują):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
KyleFarris
źródło
7
Alternatywnie, jeśli masz element:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie
1
Do Twojej wiadomości, szybsze jest użycie kolekcji selectedOptions / options niż użycie querySelectorAll.
Adam Leggett
4
Dzięki @AdamLeggett. Odwołanie się do tych, którzy nie wiedzą, że zmieniłoby markę @ kodu Someguynamedpie za wyżej: Array.from(element.selectedOptions).map(v=>v.value);.
KyleFarris
Tak, ale zobacz moją odpowiedź poniżej - w ogóle nie działa w IE i ma dziwne zachowanie w niektórych starszych wersjach Chrome i Firefox. Jeśli nie zależy Ci na wydajności, querySelectorAll lub filtering element.options załatwią sprawę. Możesz także wykonać [] .map.call () zamiast używać Array.from (), nie wiem, jaki wpływ miałoby to na wydajność, ale na pewno nie byłoby to negatywne.
Adam Leggett
stosować checked ten pracował dla mnie, na multi select listy rozwijanej, ale powinien działać na wszystkich rozwijanych, a także$(".multiple_select > option:checked").each(function(){ console.log(this.value) });
Joviano Dias
15

Jeśli chcesz iść nowocześnie, możesz to zrobić:

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

...Operatora Iterable (mapuje HTMLOptionsCollection) do tablicy.

Jeśli interesują Cię tylko wartości, możesz dodać map()wywołanie:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);
Tomáš Zato - Przywróć Monikę
źródło
Ta odpowiedź zasługuje na znacznie większe uznanie. Idealne rozwiązanie, dzięki!
Silver Ringvee
10

Najpierw użyj, Array.fromaby przekonwertować HTMLCollectionobiekt na tablicę.

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
źródło
9

$('#select-meal-type :selected') będzie zawierać tablicę wszystkich wybranych elementów.

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

Wcześniejsze

John Conde
źródło
6

Aktualizacja październik 2019

Następujące elementy powinny działać samodzielnie we wszystkich nowoczesnych przeglądarkach bez żadnych zależności ani transpilacji.

<!-- 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
źródło
4

Spróbuj tego:

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

Próbny

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

skrzypce

nieokreślony
źródło
3

jeśli chcesz, jak wyraziłeś z przerwami po każdej wartości;

$('#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
źródło
2

Jeśli chcesz zareagować na zmiany, możesz spróbować tego:

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)Jest potrzebna, ponieważ e.target.selectedOptionszwraca HTMLCollection, a nie Array. To wywołanie konwertuje je na Array, abyśmy mogli następnie zastosować mapfunkcję, która wyodrębnia wartości.

adlr0
źródło
1
Niestety nie wszędzie to zadziała, okazuje się, że IE11 nie ma pola selectedOptions. Array.prototype.slice.call(field.querySelectorAll(':checked'))
Działa
0

Coś takiego byłoby moim wyborem:

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

Jest krótki, działa szybko w nowoczesnych przeglądarkach i nie obchodzi nas, czy działa szybko, czy nie w przeglądarkach z 1% udziałem w rynku.

Zauważ, że selectedOptions zachowuje się dziwnie w niektórych przeglądarkach sprzed około 5 lat, więc węszący agent użytkownika nie jest tutaj całkowicie poza linią.

Adam Leggett
źródło
0

Możesz użyć 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>

Tang Chanrith
źródło
-1

Działa wszędzie bez 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;
};
Paul Cuddihy
źródło
selectedOptiongsnie jest obsługiwany w IE
Dustin Poissant