86

I have a <select> element with the multiple attribute. How can I get this element's selected values using JavaScript?

Here's what I'm trying:

function loopSelected() { 
    var txtSelectedValuesObj = document.getElementById('txtSelectedValues');
    var selectedArray = new Array();
    var selObj = document.getElementById('slct'); 
    var i;
    var count = 0;
    for (i=0; i<selObj.options.length; i++) { 
        if (selObj.options[i].selected) {
            selectedArray[count] = selObj.options[i].value;
            count++; 
        } 
    } 
    txtSelectedValuesObj.value = selectedArray;
}
Bugs
  • 4,456
  • 9
  • 32
  • 40
TKV
  • 2,373
  • 9
  • 41
  • 55

17 Answers17

122

No jQuery:

// Return an array of the selected opion values
// select is an HTML select element
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;
}

Quick example:

<select multiple>
  <option>opt 1 text
  <option value="opt 2 value">opt 2 text
</select>
<button onclick="
  var el = document.getElementsByTagName('select')[0];
  alert(getSelectValues(el));
">Show selected values</button>
RobG
  • 134,457
  • 30
  • 163
  • 204
  • 2
    Thank you for this answer. Could you please step through it for me? I think I understand MOST of it, but what does `var options = select && select.options;` do? In my **inexperience**, I expected that to be `var options = select.options;` – TecBrat Jan 22 '14 at 20:13
  • 13
    `select` is not the best variable name in JavaScript. – VisioN Mar 05 '14 at 11:12
  • 6
    @TecBrat `var options = select && select.options` ensures that select is not undefined, before accessing its attributes. – Qwerty Aug 11 '15 at 11:23
  • I don't think the line with && makes much sense ... if `select`is not defined `getElementById`will return `null`. In this case, `options` will be null and error once you try to access to length property. But maybe I'm missing something? – Xen_mar Aug 28 '20 at 18:31
41

ES6

[...select.options].filter(option => option.selected).map(option => option.value)

Where select is a reference to the <select> element.

To break it down:

  • [...select.options] takes the Array-like list of options and destructures it so that we can use Array.prototype methods on it (Edit: also consider using Array.from())
  • filter(...) reduces the options to only the ones that are selected
  • map(...) converts the raw <option> elements into their respective values
Rick Viscomi
  • 7,253
  • 3
  • 34
  • 48
  • 5
    Nice functional implementation :) – roadev Nov 22 '16 at 14:27
  • You could use just reduce() method [My implementation](https://stackoverflow.com/a/44574936/4725218) – To_wave Jun 15 '17 at 19:00
  • If you can get reference to using querySelectorAll? – Evgeny Jul 30 '17 at 01:00
  • 2
    @Evgeny many ways to solve it. You should post your approach in a new answer. – Rick Viscomi Jul 31 '17 at 21:41
  • This code looks much nicer than the ugly for loop over `options.length`. But is `[...select.options]` efficient in modern JS? Doesn't this iterate over whole collection three times? (i.e. first to build an array from options, second to filter, third to map) where you could do it in one go with ugly for loop – Anentropic Dec 06 '17 at 17:11
  • 2
    @Anentropic it's a good question but I don't think efficiency matters much unless we're talking about hundreds or thousands of options. – Rick Viscomi Apr 30 '18 at 00:20
29

Check-it Out:

HTML:

<a id="aSelect" href="#">Select</a>
<br />
<asp:ListBox ID="lstSelect" runat="server"  SelectionMode="Multiple" Width="100px">
    <asp:ListItem Text="Raj" Value="1"></asp:ListItem>
    <asp:ListItem Text="Karan" Value="2"></asp:ListItem>
    <asp:ListItem Text="Riya" Value="3"></asp:ListItem>
    <asp:ListItem Text="Aman" Value="4"></asp:ListItem>
    <asp:ListItem Text="Tom" Value="5"></asp:ListItem>
</asp:ListBox>

JQUERY:

$("#aSelect").click(function(){
    var selectedValues = [];    
    $("#lstSelect :selected").each(function(){
        selectedValues.push($(this).val()); 
    });
    alert(selectedValues);
    return false;
});

CLICK HERE TO SEE THE DEMO

Sukhjeevan
  • 3,308
  • 7
  • 43
  • 86
  • 2
    Not a fan - the "HTML" isn't HTML (readable, but not HTML), and the answer requires adding JQuery as a dependency. – Iiridayn Dec 29 '17 at 23:55
12

suppose the multiSelect is the Multiple-Select-Element, just use its selectedOptions Property:

//show all selected options in the console:

for ( var i = 0; i < multiSelect.selectedOptions.length; i++) {
  console.log( multiSelect.selectedOptions[i].value);
}
Shadow Wizard Says No More War
  • 64,101
  • 26
  • 136
  • 201
KAFFEECKO
  • 163
  • 2
  • 10
10

Pretty much the same as already suggested but a bit different. About as much code as jQuery in Vanilla JS:

selected = Array.prototype.filter.apply(
  select.options, [
    function(o) {
      return o.selected;
    }
  ]
);

It seems to be faster than a loop in IE, FF and Safari. I find it interesting that it's slower in Chrome and Opera.

Another approach would be using selectors:

selected = Array.prototype.map.apply(
    select.querySelectorAll('option[selected="selected"]'),
    [function (o) { return o.value; }]
);
uKolka
  • 32,643
  • 4
  • 31
  • 43
  • Isn't the functionality of the first one already in Javascript? – Arlen Beiler Mar 07 '16 at 16:28
  • 1
    Ok, got it. But the first one can be shorter. Just `select.selectedOptions`. – Arlen Beiler Mar 07 '16 at 16:34
  • 1
    That's a drawback of bare JS compared to using libraries. The selectedOptions property lacks in [reliable browser support](http://stackoverflow.com/questions/10711767/is-selectedoptions-broken-or). Library like jQuery will hide that from you. A lot has changed since 2013 but a quick google shows that people still have issues with selectedOptions. – uKolka Mar 07 '16 at 20:19
6

Check this:

HTML:

<select id="test" multiple>
<option value="red" selected>Red</option>
<option value="rock" selected>Rock</option>
<option value="sun">Sun</option>
</select>

Javascript one line code

Array.from(document.getElementById("test").options).filter(option => option.selected).map(option => option.value);
Yaseen Ahmad
  • 1,789
  • 5
  • 22
  • 42
Krish K
  • 86
  • 1
  • 2
4

Here is an ES6 implementation:

value = Array(...el.options).reduce((acc, option) => {
  if (option.selected === true) {
    acc.push(option.value);
  }
  return acc;
}, []);
To_wave
  • 474
  • 1
  • 6
  • 16
  • This works great. It's interesting to note that because `element.options` is a live collection, it cannot be reduced. It must first be converted to an Array as seen in the above answer. – Brandon Jun 15 '17 at 18:57
4

Building on Rick Viscomi's answer, try using the HTML Select Element's selectedOptions property:

let txtSelectedValuesObj = document.getElementById('txtSelectedValues');
[...txtSelectedValuesObj.selectedOptions].map(option => option.value);

In detail,

  • selectedOptions returns a list of selected items.
  • Specifically, it returns a read-only HTMLCollection containing HTMLOptionElements.
  • ... is spread syntax. It expands the HTMLCollection's elements.
  • [...] creates a mutable Array object from these elements, giving you an array of HTMLOptionElements.
  • map() replaces each HTMLObjectElement in the array (here called option) with its value (option.value).

Dense, but it seems to work.

Watch out, selectedOptions isn't supported by IE!

Kevin W Matthews
  • 580
  • 5
  • 17
2

You Can try this script

     <!DOCTYPE html>
    <html>
    <script>
    function getMultipleSelectedValue()
    {
      var x=document.getElementById("alpha");
      for (var i = 0; i < x.options.length; i++) {
         if(x.options[i].selected ==true){
              alert(x.options[i].value);
          }
      }
    }
    </script>
    </head>
    <body>
    <select multiple="multiple" id="alpha">
      <option value="a">A</option>
      <option value="b">B</option>
      <option value="c">C</option>
      <option value="d">D</option>
    </select>
    <input type="button" value="Submit" onclick="getMultipleSelectedValue()"/>
    </body>
    </html>
Pankaj Chauhan
  • 1,465
  • 13
  • 12
2

You can use [].reduce for a more compact implementation of RobG's approach:

var getSelectedValues =  function(selectElement) {
  return [].reduce.call(selectElement.options, function(result, option) {
    if (option.selected) result.push(option.value);
    return result;
  }, []);
};
Community
  • 1
  • 1
rouan
  • 3,579
  • 4
  • 21
  • 33
2

My template helper looks like this:

 'submit #update': function(event) {
    event.preventDefault();
    var obj_opts = event.target.tags.selectedOptions; //returns HTMLCollection
    var array_opts = Object.values(obj_opts);  //convert to array
    var stray = array_opts.map((o)=> o.text ); //to filter your bits: text, value or selected
    //do stuff
}
Steve Taylor
  • 410
  • 1
  • 4
  • 11
1

Same as the earlier answer but using underscore.js.

function getSelectValues(select) {
    return _.map(_.filter(select.options, function(opt) { 
        return opt.selected; }), function(opt) { 
            return opt.value || opt.text; });
}
F. P. Freely
  • 870
  • 14
  • 21
1

Here ya go.

const arr = Array.from(el.features.selectedOptions) //get array from selectedOptions property
const list = [] 
arr.forEach(item => list.push(item.value)) //push each item to empty array
console.log(list)
0

Riot js code

this.GetOpt=()=>{

let opt=this.refs.ni;

this.logger.debug("Options length "+opt.options.length);

for(let i=0;i<=opt.options.length;i++)
{
  if(opt.options[i].selected==true)
    this.logger.debug(opt.options[i].value);
}
};

//**ni** is a name of HTML select option element as follows
//**HTML code**
<select multiple ref="ni">
  <option value="">---Select---</option>
  <option value="Option1 ">Gaming</option>
  <option value="Option2">Photoshoot</option>
</select>
Nilesh Pawar
  • 627
  • 7
  • 11
0

You may use jquery plugin chosen .

<head>
 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/chosen/1.4.2/chosen.min.css"
 <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
 <script src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.4.2/chosen.jquery.min.js"></script>
 <script>
        jQuery(document).ready(function(){
            jQuery(".chosen").data("placeholder","Select Frameworks...").chosen();
        });
 </script>
</head>

 <body> 
   <label for="Test" class="col-md-3 control label">Test</label>
      <select class="chosen" style="width:350px" multiple="true">
            <option>Choose...</option>
            <option>Java</option>                           
            <option>C++</option>
            <option>Python</option>
     </select>
 </body>
rashedcs
  • 3,209
  • 2
  • 35
  • 39
0

You can create your own function like this and use it everywhere

Pure JS

/**
* Get values from multiple select input field
* @param {string} selectId - the HTML select id of the select field
**/
function getMultiSelectValues(selectId) {
 // get the options of select field which will be HTMLCollection
 // remember HtmlCollection and not an array. You can always enhance the code by
 // verifying if the provided select is valid or not
  var options = document.getElementById(selectId).options; 
    var values = [];
    
   // since options are HtmlCollection, we convert it into array to use map function on it
    Array.from(options).map(function(option) {
        option.selected ? values.push(option.value) : null
    })

    return values;
}

you can get the same result using jQuery in a single line

$('#select_field_id').val()

and this will return the array of values of well.

Dharman
  • 26,923
  • 21
  • 73
  • 125
Koushik Das
  • 7,573
  • 3
  • 39
  • 37
0

Example from HTMLSelectElement.selectedOptions - Web APIs | MDN

let orderButton = document.getElementById("order");
let itemList = document.getElementById("foods");
let outputBox = document.getElementById("output");

orderButton.addEventListener("click", function() {
  let collection = itemList.selectedOptions;
  let output = "";

  for (let i = 0; i < collection.length; i++) {
    if (output === "") {
      output = "Your order for the following items has been placed: ";
    }
    output += collection[i].label;

    if (i === (collection.length - 2) && (collection.length < 3)) {
      output += " and ";
    } else if (i < (collection.length - 2)) {
      output += ", ";
    } else if (i === (collection.length - 2)) {
      output += ", and ";
    }
  }

  if (output === "") {
    output = "You didn't order anything!";
  }

  outputBox.innerHTML = output;
}, false);
<label for="foods">What do you want to eat?</label><br>
<select id="foods" name="foods" size="7" multiple>
  <option value="1">Burrito</option>
  <option value="2">Cheeseburger</option>
  <option value="3">Double Bacon Burger Supreme</option>
  <option value="4">Pepperoni Pizza</option>
  <option value="5">Taco</option>
</select>
<br>
<button name="order" id="order">
  Order Now
</button>
<p id="output">
</p>
Ooker
  • 1,276
  • 3
  • 21
  • 49