Como obter todos os valores selecionados de <select multiple = multiple>?


115

Pareceu estranho não consegui encontrar este já perguntado, mas aqui vai!

Eu tenho um html da seguinte maneira:

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

Como obtenho todos os valores (uma matriz?) Que o usuário selecionou em javascript?

Por exemplo, se o usuário selecionou Almoço e Lanches, quero uma matriz de {2, 4}.

Parece que deveria ser uma tarefa muito simples, mas não consigo fazer isso.

Obrigado.




Respostas:


105

A maneira usual:

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

Dos documentos :

No caso de <select multiple="multiple">elementos, o .val()método retorna um array contendo cada opção selecionada;


10
@augurone: Eu afirmo que é?
Felix Kling

9
@FelixKling, você enganou alguém que pode imediatamente incluir o jQuery lib inteiro apenas para isso, antes de perceber que não deveria, a menos que realmente precise.
Aamir Afridi

32
@AamirAfridi: a questão está marcada com jQuery. Marcar uma pergunta com uma biblioteca geralmente significa que o op usa essa biblioteca e que as respostas que fazem uso da biblioteca são bem-vindas. Eu também sugeriria uma porta alternativa para o jQuery hoje? Talvez. Mas esta pergunta tem mais de 3 anos. Veja também o comentário do OP sobre a outra resposta: stackoverflow.com/questions/11821261/…
Felix Kling

12
Você está certo. Faz sentido se a pergunta estiver marcada com jQuery 😐
Aamir Afridi

148

A menos que uma pergunta seja feita por JQuery, a pergunta deve ser respondida primeiro em javascript padrão, pois muitas pessoas não usam JQuery em seus sites.

De RobG Como obter todos os valores selecionados de uma caixa de seleção múltipla 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;
}

24
Está marcado com jquery.
Kyle

1
ha, não vi isso: / ainda +1
mw_21 01 de

6
Sobre o quê selectedOptions? Não é cross-browser suficiente? Array.prototype.map.call(el.selectedOptions, function(x){ return x.value })
tenbits

Observe que quando não há nenhum valueatributo, então opt.value= opt.text.
thdoan

1
Finalmente! Baunilha ... meu sabor favorito
papiro

46

Na verdade, descobri que a maneira melhor, mais sucinta, mais rápida e mais compatível de usar JavaScript puro (presumindo que você não precise dar suporte total ao IE lte 8) é a seguinte:

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

ATUALIZAÇÃO (14/02/2017):

Uma forma ainda mais sucinta usando ES6 / ES2015 (para os navegadores que o suportam):

const selected = document.querySelectorAll('#select-meal-type option:checked');
const values = Array.from(selected).map(el => el.value);

7
Como alternativa, se você tiver o elemento:Array.from(element.querySelectorAll("option:checked"),e=>e.value);
Someguynamedpie

1
Apenas para sua informação, é mais rápido usar a coleção selectedOptions / options do que usar querySelectorAll.
Adam Leggett

4
Obrigado @AdamLeggett. Para referência para aqueles que não sabem, que mudaria make @ código de Someguynamedpie acima para: Array.from(element.selectedOptions).map(v=>v.value);.
KyleFarris

Sim, mas veja minha resposta abaixo - não funciona no IE e tem um comportamento estranho em algumas versões mais antigas do Chrome e do Firefox. Se você não se preocupa com o desempenho, querySelectorAll ou filtering element.options dão conta do recado. Além disso, você pode fazer [] .map.call () em vez de usar Array.from (), não sei que impacto isso teria no desempenho, mas certamente não seria negativo.
Adam Leggett

usado checked Isso funcionou para mim, em um menu suspenso de seleção múltipla, mas deve funcionar para todos os menus suspensos também$(".multiple_select > option:checked").each(function(){ console.log(this.value) });
Joviano Dias

15

Se você quiser seguir o caminho moderno, pode fazer o seguinte:

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

O ...operador mapeia iterable ( HTMLOptionsCollection) para a matriz.

Se você está interessado apenas nos valores, pode adicionar uma map()chamada:

const selectedValues = [...field.options]
                     .filter((x) => x.selected)
                     .map((x)=>x.value);

Essa resposta merece muito mais crédito. Solução perfeita, obrigado!
Silver Ringvee

10

Primeiro, use Array.frompara converter o HTMLCollectionobjeto em uma 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

9

$('#select-meal-type :selected') irá conter uma matriz de todos os itens selecionados.

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


6

Atualização de outubro de 2019

O seguinte deve funcionar "autônomo" em todos os navegadores modernos sem quaisquer dependências ou transpilação.

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

4

Experimente isto:

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

rabeca


3

se quiser como expressou com intervalos após 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
})

2

Se você precisar responder às mudanças, pode tentar o seguinte:

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

O [].slice.call(e.target.selectedOptions)é necessário porque e.target.selectedOptionsretorna um HTMLCollection, não um Array. Essa chamada o converte em Arraypara que possamos então aplicar a mapfunção, que extrai os valores.


1
Infelizmente, isso não funcionará em todos os lugares, mas o IE11 não tem o campo selectedOptions. No entanto, o seguinte funciona:Array.prototype.slice.call(field.querySelectorAll(':checked'))
JamesDev

0

Algo como o seguinte seria minha escolha:

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

É curto, é rápido em navegadores modernos e não nos importamos se é rápido ou não em navegadores de 1% do mercado.

Observe que o selectedOptions tem um comportamento instável em alguns navegadores há cerca de 5 anos, então um user agent sniff não está totalmente fora de linha aqui.


0

Você pode 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>


-1

Funciona em qualquer lugar sem 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;
};

selectedOptiongsnão é compatível com o IE
Dustin Poissant
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.