0

I need to map to an array the selected options inside select element (multiple selection is enable).

Here is the html:

<select id="listado" size="5" multiple>
    <option value="Leer" id="aficion-leer">Leer</option>
    <option value="Programar" id="aficion-programar">Programar</option>
    <option value="Cine" id="aficion-cine">Cine</option>
    <option value="Deporte" id="aficion-deporte">Deporte</option>
</select>

I tried this: Array.from(document.querySelector("#listado")).map(elemento => elemento.value); which returns every option. According to this answer, adding option:checked to the query param should do the trick, but I get an empty list.

Any idea on what the reason might be?

Luis Fernandez
  • 539
  • 1
  • 4
  • 24

2 Answers2

1

You can use document.querySelectorAll and only select options that are checked, then map them.

let options=[...document.querySelectorAll("#listado option:checked")].map(elemento => elemento.value)
console.log(options)
<select id="listado" size="5" multiple>
  <option value="Leer" id="aficion-leer">Leer</option>
  <option value="Programar" id="aficion-programar" selected>Programar</option>
  <option value="Cine" id="aficion-cine">Cine</option>
  <option value="Deporte" id="aficion-deporte" selected>Deporte</option>
</select>
ikiK
  • 6,328
  • 4
  • 20
  • 40
  • What do the triple dots do here? I thought they were used to make copies of objects but I don't see how that'd be useful in this situation, yet it doesn't work without them. – Luis Fernandez Feb 19 '21 at 16:09
  • 1
    @LuisFernandez Its called Spread operator read about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax Its because `querySelectorAll` returns a list, not array, so you have to put those list items in array in order to map it. – ikiK Feb 19 '21 at 16:15
  • That' right, but it is more safe to use `Array.from` – blaumeise20 Feb 19 '21 at 16:21
  • You can use for each without spread operator and then push values from the list: let `options = [] document.querySelectorAll("#listado option:checked").forEach(elemento => options.push(elemento.value))` @LuisFernandez – ikiK Feb 19 '21 at 16:22
  • @blaumeise20 Hows that? – ikiK Feb 19 '21 at 16:23
  • Yeah, that's also possible. But I think it is faster and more compatible to old browsers when you use `Array.from` – blaumeise20 Feb 19 '21 at 16:58
1

Have you tried this?

console.log(
    Array.from(document.querySelector("#listado").childNodes).filter(elemento => elemento.selected).map(elemento => elemento.value) // this line
);
<select id="listado" size="5" multiple>
    <option value="Leer" id="aficion-leer">Leer</option>
    <option value="Programar" id="aficion-programar" selected>Programar</option> <!-- selected for demo -->
    <option value="Cine" id="aficion-cine">Cine</option>
    <option value="Deporte" id="aficion-deporte">Deporte</option>
</select>
blaumeise20
  • 2,148
  • 8
  • 26