在select下拉多选的时候,希望部分下拉选项不能同时选。部分选项之间达到互斥的效果。
场景分析
select的插件是bootstrap-select的插件。由于原生插件不支持这样的属性,需要修改插件源码。
第一版
利用bootstrap-select的插件自身支持的分组理念,将互斥的分在不同分组里面,不同的分组里面的选项不能同时选。若是选了将取消其他分组的选择,只保留当前分组的选择,并提示相关信息。
this.$menu.on('click', 'li a', function (e) {
//Don't run if we have been disabled
if (!that.multiple) { // Deselect all others if not multi select box{
//.......
}else if(that.options.onlyOneGroup){//添加了一个默认属性,来支持
var optID = 0,preOpts=0,curOpts=0,nextOpts=0;
$option.prop('selected', !state);
that.setSelected(clickedIndex, !state);
$this.blur();
//1. 当前分组已选择的和所有已选的对比,如果前者大说明选了两个组
var maxReached = $options.filter(':selected').length,
maxReachedGrp = $optgroup.find('option:selected').length;
if(maxReached>maxReachedGrp){
//2. 取消其他的分组选择
$optgroup.prevAll().each(function(){
preOpts += $(this).find('option').length
})
$optgroup.nextAll().each(function(){
nextOpts += $(this).find('option').length
})
curOpts=$optgroup.find('option').length
for(var i=0;i<preOpts;i++){
that.$menu.find('.selected').filter("[data-original-index='"+i+"']").removeClass('selected')
}
for(var i=preOpts+curOpts;i<preOpts+curOpts+nextOpts;i++){
that.$menu.find('.selected').filter("[data-original-index='"+i+"']").removeClass('selected')
}
$optgroup.siblings().find('option:selected').removeClass('selected')
$optgroup.siblings().find('option:selected').prop('selected', false)
//that.$menu.find('.selected').removeClass('selected');
//that.setSelected(clickedIndex, false);
//3. 提示信息
var $notify = $('<div class="notify"></div>'),maxTxtGrp=that.options.selectLimit;//自己添加的提示信息
// If {var} is set in array, replace it
// $option.prop('selected', false);
that.$menu.append($notify);
$notify.append($('<div>' + maxTxtGrp + '</div>'));
that.$element.trigger('maxReachedGrp.bs.select');
// setTimeout(function () {
// that.setSelected(clickedIndex, false);
//}, 10);
$notify.delay(750).fadeOut(300, function () {
$(this).remove();
});
}
}else{ // Toggle the one we have chosen if we are multi select.
//.......
}
说明:bootstrap-select的版本不同,上面代码可能需要依据实际版本做一个小的变动
效果展示
<select class="selectpicker" multiple data-max-options="2">
<optgroup data-max-options="2">
<option>Mustard</option>
<option>Ketchup</option>
<option>Relish</option>
</optgroup>
<optgroup data-max-options="2">
<option>Plain</option>
<option>Steamed</option>
<option>Toasted</option>
</optgroup>
<optgroup data-max-options="2">
<option>Plain</option>
<option>Steamed</option>
<option>Toasted</option>
</optgroup>
</select>
- 先选第一分组中的选项
- 再选第二个分组中选项,会取消前一个分组中选项,同时提示信息。