Comment obtenir toutes les valeurs sélectionnées de <select multiple = multiple>?

115

Cela a semblé étrange, je n'ai pas trouvé celui-ci déjà demandé, mais c'est parti!

J'ai un html comme suit:

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

Comment obtenir toutes les valeurs (un tableau?) Que l'utilisateur a sélectionnées en javascript?

Par exemple, si l'utilisateur a sélectionné Déjeuner et collations, je veux un tableau de {2, 4}.

Cela semble être une tâche très simple, mais je n'arrive pas à le faire.

Merci.

Kyle
la source

Réponses:

105

La manière habituelle:

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

À partir de la documentation :

Dans le cas des <select multiple="multiple">éléments, la .val()méthode renvoie un tableau contenant chaque option sélectionnée;

Félix Kling
la source
10
@augurone: Dois-je le prétendre?
Felix Kling
9
@FelixKling vous venez de tromper quelqu'un qui pourrait tout de suite inclure toute la lib jQuery juste pour cela avant qu'il ne se rende compte qu'il ne devrait pas le faire à moins qu'il n'en ait vraiment besoin.
Aamir Afridi
32
@AamirAfridi: la question est taguée avec jQuery. Marquer une question avec une bibliothèque signifie généralement que l'op utilise cette bibliothèque et que les réponses utilisant la bibliothèque sont les bienvenues. Est-ce que je suggérerais également un moyen alternatif Ina porte sur jQuery aujourd'hui? Peut être. Mais cette question a plus de 3 ans. Voir également le commentaire du PO sur l'autre réponse: stackoverflow.com/questions/11821261/…
Felix Kling
12
Vous avez raison. Cela a du sens si la question est taguée avec jQuery 😐
Aamir Afridi
148

Sauf si une question demande JQuery, la question doit d'abord être répondue en javascript standard car de nombreuses personnes n'utilisent pas JQuery dans leurs sites.

De RobG Comment obtenir toutes les valeurs sélectionnées d'une boîte de sélection multiple en utilisant 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
la source
24
Il est tagué avec jquery.
Kyle
1
ha,
je n'ai
6
Et quoi selectedOptions? N'est-ce pas assez cross-browser? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbits
Notez que lorsqu'il n'y a pas d' valueattribut, alors opt.value= opt.text.
thdoan
1
Finalement! Vanille ... ma saveur préférée
papiro
46

En fait, j'ai trouvé la meilleure façon, la plus succincte, la plus rapide et la plus compatible d'utiliser du JavaScript pur (en supposant que vous n'ayez pas besoin de prendre entièrement en charge IE lte 8) est la suivante:

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

MISE À JOUR (2017-02-14):

Une manière encore plus succincte d'utiliser ES6 / ES2015 (pour les navigateurs qui le prennent en charge):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
KyleFarris
la source
7
Alternativement, si vous avez l'élément:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie
1
Juste pour info, il est plus rapide d'utiliser la collection selectedOptions / options que d'utiliser querySelectorAll.
Adam Leggett
4
Merci @AdamLeggett. Pour référence à ceux qui ne connaissent pas, cela changerait faire @ code de Someguynamedpie ci - dessus à: Array.from(element.selectedOptions).map(v=>v.value);.
KyleFarris
Ce serait le cas, mais voyez ma réponse ci-dessous - cela ne fonctionne pas du tout sur IE et a un comportement étrange dans certaines anciennes versions de Chrome et Firefox. Si vous ne vous souciez pas des performances, querySelectorAll ou filtering element.options fait le travail. Aussi, vous pouvez faire [] .map.call () au lieu d'utiliser Array.from (), je ne sais pas quel impact cela aurait sur les performances mais ce ne serait certainement pas négatif.
Adam Leggett
utilisé checked Cela a fonctionné pour moi, sur une liste déroulante à sélection multiple, mais devrait également fonctionner pour toutes les listes déroulantes$(".multiple_select > option:checked").each(function(){ console.log(this.value) });
Joviano Dias
15

Si vous voulez opter pour la voie moderne, vous pouvez le faire:

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

L' ...opérateur mappe iterable ( HTMLOptionsCollection) au tableau.

Si vous êtes simplement intéressé par les valeurs, vous pouvez ajouter un map()appel:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);
Tomáš Zato - Réintégrer Monica
la source
Cette réponse mérite bien plus de crédit. Solution parfaite, merci!
Silver Ringvee
10

Tout d'abord, utilisez Array.frompour convertir l' HTMLCollectionobjet en tableau.

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
la source
9

$('#select-meal-type :selected') contiendra un tableau de tous les éléments sélectionnés.

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

John Conde
la source
6

Mise à jour octobre 2019

Ce qui suit devrait fonctionner "autonome" sur tous les navigateurs modernes sans aucune dépendance ni 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>
Fergie
la source
4

Essaye ça:

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

Démo

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

violon

indéfini
la source
3

si vous voulez comme vous l'avez exprimé avec des pauses après chaque valeur;

$('#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
})
écrivain
la source
2

Si vous avez besoin de répondre aux modifications, vous pouvez essayer ceci:

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

Le [].slice.call(e.target.selectedOptions)est nécessaire car e.target.selectedOptionsrenvoie a HTMLCollection, pas un Array. Cet appel le convertit en Arrayafin que nous puissions ensuite appliquer la mapfonction, qui extrait les valeurs.

adlr0
la source
1
Malheureusement, cela ne fonctionnera pas partout, il s'avère que IE11 n'a pas le champ selectedOptions. Ce qui suit fonctionne cependant:Array.prototype.slice.call(field.querySelectorAll(':checked'))
JamesDev
0

Quelque chose comme ce qui suit serait mon choix:

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

C'est court, c'est rapide sur les navigateurs modernes, et nous ne nous soucions pas de savoir si c'est rapide ou non sur les navigateurs à 1% de part de marché.

Notez que selectedOptions a un comportement bancal sur certains navigateurs il y a environ 5 ans, donc un sniff d'agent utilisateur n'est pas totalement hors de propos ici.

Adam Leggett
la source
0

Vous pouvez utiliser 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
la source
-1

Fonctionne partout sans 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
la source
selectedOptiongsn'est pas pris en charge dans IE
Dustin Poissant