How to get multiple selected options value in React JS?

22.3k Views Asked by At
<Multiselect label='Select College' ref="collegeList" onChange={this.handleChange} multiple >
         <option value='college1'>college1</option>
         <option value='college2'>college2</option>
</Multiselect>

This component is from https://github.com/skratchdot/react-bootstrap-multiselect

What should be written inside the handleChange() function ?

7

There are 7 best solutions below

0
On BEST ANSWER

Unfortunately, react-bootstrap-multiselect doesn't seem to expose any sort of API for getting the currently selected items, so you'll have to query them from the DOM directly. Try something like this:

handleChange: function () {
    var node = React.findDOMNode(this.refs.collegeList);
    var options = [].slice.call(node.querySelectorAll('option'));
    var selected = options.filter(function (option) {
        return option.selected;
    });
    var selectedValues = selected.map(function (option) {
        return option.value;
    });

    console.log(selectedValues);
}

If you're using jQuery, this can be simplified a bit to:

handleChange: function () {
    var node = $(React.findDOMNode(this.refs.collegeList));
    var selectedValues = node.children('option:selected').map(function(option) {
        return option.value;
    });

    console.log(selectedValues);
}
0
On

I would suggest to have a state in your component called selectedItems

The onChange callback then, takes as parameters element and checked, from the Bootstrap Multiselect docs. Element has the val() method, which returns the value assigned to the option.

Therefore handleChange could be implemented in the following way

handleChange: function (element, checked) {
    var newSelectItems = _.extend({}, this.state.selectItems);
    newSelectItems[element.val()] = checked;
    this.setState({selectItems: newSelectItems})
},
getInitialState: function () {
     return {selectItems: {}};
}

In this way, every time an element is clicked, its checked attribute is saved in the component state, which is quite handy if you need to change anything based on the MultiSelect selected values.

Please note that for the above code you need either the Underscore or the Lodash library. This is necessary as React cannot merge nested objects, as answered here.

0
On

React 16 with TS.

Note: refs are deprecated, that's why I used callback function to set Ref.

  private selectInput: any;
  private setSelectRef = element => {
    this.selectInput = element;
  };
  private handleMultiSelectChange = () => {
    const selected = [...this.selectInput.refs.MultiselectInternal.selectRef].filter(option => option.selected)
      .map(option => option.value);
     // there you can update your state using this.setState()
  };

...

<Multiselect data={data}
   onChange={this.handleMultiSelectChange}
   multiple={true}
   ref={this.setSelectRef}
   buttonClass="btn btn-default"
/>
0
On

A much simpler and a direct way to get the values:

handleChange: function () {
   var selectedValues = this.refs.collegeList.$multiselect.val();
   console.log(selectedValues);
}
0
On

clean es6 code using selectedOptions

let selected = [...this.refs.collegeList.selectedOptions].map(o => o.value);
0
On

you can use selectedOption that return a htmlCollection like this

 onchange(e){
        let selected=[];//will be selected option in select
        let selected_opt=(e.target.selectedOptions);
        console.log(selected_opt)
        for (let i = 0; i < selected_opt.length; i++){
            selected.concat(selected_opt.item(i).value)
        }

    }

and our select

<select  onChange={this.onchange.bind(this)} className="selectpicker w-100 rtl" multiple >
                    {this.state.list.map(obj=><option value={obj[this.props.val]}>{obj[this.props.name]}</option>)}
                </select>
2
On

Here's a much cleaner, es6 way to do it :)

let selected = [...this.refs.select]
  .filter(option => option.selected)
  .map(option => option.value)

There you go, all of the selected options!