Ad

ReactJS/Semantic-UI DropDown MaxSelection

- 1 answer

Well, I searched a lot but nothing found, I decided to solve it on my own but stuck in middle it. Let me explain first, There is an option for limit selection in Semantic-Ui but not in React version, here you can find maxSelections in Multiple Select Settings section, but there is no such option for reactjs version, and if you use this option maxselections nothing happen:

<Dropdown placeholder='Skills' fluid multiple selection options={options} maxselections={2} />

Here is a similar question asked, but it's not working at all and looks not user friendly, and just make selected into an array but what I want is stop selecting user and at least get a small error. Actually I looking something like this.

So let's see what I tried so far:

Here is default data from json:

const data = {
    options: [
        {id: 1, name: "example1"},
        {id: 2, name: "example2"},
        {id: 3, name: "example3"},
        {id: 4, name: "example4"},
        {id: 5, name: "example5"}
    ]
};

const option = data.options.map((obj) => ({
    key: obj.id,
    text: obj.name,
    value: obj.name
}));

Here is state:

this.state = {
    limit: false,
    selectOption: option
};

And this is handler:

getSelected  = (e, {value}) => {

const selectedOption = []

for(let i=1;value.length> i;i++){
    selectedOption.push({id: i, name: value[i]});
}

const fake = selectedOption.map((obj) => ({
    key: obj.id,
    text: obj.name,
    value: obj.name
}));

if(value.length === 2) {
    this.setState({
        limit: true,
        selectOption: fake
    })
} else {
        this.setState({
            limit: false,
            selectOption: option
        }) 
    }
}

And finally:

  <Dropdown placeholder='Skills' fluid multiple selection options={this.state.selectOption} onChange={this.getSelected} closeOnChange={this.state.limit ? true : false}/>

The logic is, if user reach to maximum selected, close dropdown then just show selected value in dropdown, then if less than show default options again. I'm not resist to this logic, maybe this is not a good practice for do this, if you have any idea please let me know. But in current code the problem is, options={options} update with just one selected values.

Ad

Answer

I solved it myself and decided to post it as answer for other peoples in future. I removed for loop and also map and used forEach and this working good:

getSelected  = (e, {value}) => {

const selectedOption = []

value.forEach(function(v, i) {
    selectedOption.push({key: i, text: v, value: v});
});

if(value.length === 2) {
alert('You can only select 2 options') //show error

    this.setState({
        limit: true,
        selectOption: selectedOption
    })
} else {
    this.setState({
        limit: false,
        selectOption: option
    })
}
}

If anyone use id in value instead of text go with this:

getSelected  = (e, data) => {
...

data.value.forEach(function(i) {
    const opt = data.options.find(o => o.value === i);
    selectedOption.push({key: i, text: opt.text, value: i});
});
Ad
source: stackoverflow.com
Ad