¿Cómo obtener todos los valores seleccionados de <select multiple = multiple>?

115

Parecía extraño que no pudiera encontrar este ya preguntado, ¡pero aquí va!

Tengo un html de la siguiente manera:

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

¿Cómo obtengo todos los valores (¿una matriz?) Que el usuario ha seleccionado en javascript?

Por ejemplo, si el usuario ha seleccionado Almuerzo y bocadillos, quiero una matriz de {2, 4}.

Esto parece que debería ser una tarea muy simple, pero parece que no puedo hacerlo.

Gracias.

Kyle
fuente

Respuestas:

105

La forma habitual:

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

De los documentos :

En el caso de los <select multiple="multiple">elementos, el .val()método devuelve una matriz que contiene cada opción seleccionada;

Felix Kling
fuente
10
@augurone: ¿Afirmo que lo es?
Felix Kling
9
@FelixKling, acabas de engañar a alguien que podría incluir de inmediato la biblioteca jQuery completa solo por esto antes de darse cuenta de que no debería hacerlo a menos que realmente lo necesite.
Aamir Afridi
32
@AamirAfridi: la pregunta está etiquetada con jQuery. Etiquetar una pregunta con una biblioteca generalmente significa que el operador usa esa biblioteca y que las respuestas que hacen uso de la biblioteca son bienvenidas. ¿Sugeriría también una forma alternativa de que Ina puerta a jQuery hoy? Tal vez. Pero esta pregunta tiene más de 3 años. También vea el comentario del OP sobre la otra respuesta: stackoverflow.com/questions/11821261/…
Felix Kling
12
Tienes razón. Tiene sentido si la pregunta está etiquetada con jQuery 😐
Aamir Afridi
148

A menos que una pregunta solicite JQuery, la pregunta debe responderse primero en javascript estándar, ya que muchas personas no usan JQuery en sus sitios.

De RobG ¿Cómo obtener todos los valores seleccionados de un cuadro de selección múltiple usando 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
fuente
24
Está etiquetado con jquery.
Kyle
1
ja, no vi eso: / todavía +1
mw_21
6
¿Qué hay de selectedOptions? ¿No es suficiente para varios navegadores? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbits
Tenga en cuenta que cuando no hay ningún valueatributo, entonces opt.value= opt.text.
thdoan
1
¡Finalmente! Vainilla ... mi sabor favorito
papiro
46

En realidad, encontré que la mejor, más sucinta, rápida y más compatible forma usando JavaScript puro (asumiendo que no necesitas ser totalmente compatible con IE lte 8) es la siguiente:

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

ACTUALIZACIÓN (2017-02-14):

Una forma aún más sucinta usando ES6 / ES2015 (para los navegadores que lo admiten):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);
KyleFarris
fuente
7
Alternativamente, si tiene el elemento:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie
1
Solo para su información, es más rápido usar la colección selectedOptions / options que usar querySelectorAll.
Adam Leggett
4
Gracias @AdamLeggett. A modo de referencia a los que no lo saben, que iba a cambiar el código del maquillaje @ Someguynamedpie arriba a: Array.from(element.selectedOptions).map(v=>v.value);.
KyleFarris
Lo haría, pero vea mi respuesta a continuación: no funciona en absoluto en IE y tiene un comportamiento extraño en algunas versiones anteriores de Chrome y Firefox. Si no le importa el rendimiento, querySelectorAll o filtrar element.options hace el trabajo. Además, puede hacer [] .map.call () en lugar de usar Array.from (), no sé qué impacto tendría esto en el rendimiento, pero ciertamente no sería negativo.
Adam Leggett
usado checked Esto funcionó para mí, en un menú desplegable de selección múltiple, pero también debería funcionar para todos los menús desplegables$(".multiple_select > option:checked").each(function(){ console.log(this.value) });
Joviano Dias
15

Si quieres seguir el camino moderno, puedes hacer esto:

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

El ...operador mapea iterable (HTMLOptionsCollection ) a la matriz.

Si solo está interesado en los valores, puede agregar una map()llamada:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);
Tomáš Zato - Reincorporar a Monica
fuente
Esta respuesta merece mucho más crédito. Solución perfecta, gracias!
Silver Ringvee
10

Primero, use Array.frompara convertir el HTMLCollectionobjeto en una matriz.

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

$('#select-meal-type :selected') contendrá una matriz de todos los elementos seleccionados.

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

John Conde
fuente
6

Actualización de octubre de 2019

Lo siguiente debería funcionar de forma "independiente" en todos los navegadores modernos sin dependencias ni transpilación.

<!-- 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
fuente
4

Prueba esto:

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

Manifestación

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

violín

indefinido
fuente
3

si lo desea como expresó con descansos después de cada valor;

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

Si necesita responder a los cambios, puede intentar esto:

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

El [].slice.call(e.target.selectedOptions)es necesario porque e.target.selectedOptionsdevuelve un HTMLCollection, no un Array. Esa llamada lo convierte para Arrayque luego podamos aplicar la mapfunción, que extrae los valores.

adlr0
fuente
1
Lamentablemente, esto no funcionará en todas partes, resulta que IE11 no tiene el campo selectedOptions. A continuación se hace el trabajo, sin embargo:Array.prototype.slice.call(field.querySelectorAll(':checked'))
JamesDev
0

Algo como lo siguiente sería mi elección:

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

Es breve, es rápido en los navegadores modernos y no nos importa si es rápido o no en los navegadores con una participación de mercado del 1%.

Tenga en cuenta que selectedOptions tiene un comportamiento inestable en algunos navegadores desde hace unos 5 años, por lo que un rastreo de agente de usuario no está totalmente fuera de lugar aquí.

Adam Leggett
fuente
0

Puedes usar 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
fuente
-1

Funciona en todas partes sin 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
fuente
selectedOptiongsno es compatible con IE
Dustin Poissant