简体   繁体   English

ReactJS/Semantic-UI DropDown MaxSelection

[英]ReactJS/Semantic-UI DropDown MaxSelection

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:我先解释一下, Semantic-Ui中有限制选择的选项,但React版本没有,这里你可以在Multiple Select Settings部分找到maxSelections ,但是reactjs版本没有这个选项,如果你使用这个选项maxselections什么都没发生:

<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. 是一个类似的问题,但它根本不起作用,看起来对用户不友好,只是将 selected 放入一个数组中,但我想要的是停止选择用户并至少得到一个小错误。 Actually I looking something like this .其实我看起来像这样

So let's see what I tried so far:所以让我们看看到目前为止我尝试了什么:

Here is default data from json :这是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 :这是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.但在当前代码中,问题是 options={options} 仅使用一个选定值进行更新。

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:我删除for循环和map并使用了forEach ,这很好用:

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:如果有人在value中使用id而不是text go :

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});
});

Quite an old issue.很老的问题了。 But I'm posting my workaround here.但我在这里发布我的解决方法。 It's short and simple.它简短而简单。

At first, save the values in the state (preferably redux state) after every onChange.首先,在每次 onChange 之后保存 state(最好是 redux 状态)中的值。 React state also would do fine. React state 也可以。 Then, make it disabled when a certain array length of the value is reached.然后,在达到某个值的数组长度时将其禁用。

const districtData = ['Dhaka', 'Bagerhat', 'Bandarban', 
'Barguna', 'Barishal', 'Bhola']

const [districtValue, setDistrictValue] = useState();

<Dropdown
onChange={async (e, { name, value }) => {setDistrictValue(value)}}
options={districtData.map((currentValue, index) => {
    return {
    key: `${currentValue}`,
    value: `${currentValue}`,
    text: `${currentValue}`,
    disabled: districtValue.length > 2 ? true : false 
}
// Do other things here
// Max 3 values here, then options will be disabled. 
// Will be live again if any selected option is less than 3                 

/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM