bootstrap-select 下拉互斥

在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>
  1. 先选第一分组中的选项
  2. 再选第二个分组中选项,会取消前一个分组中选项,同时提示信息。
    第一步
    第二步

参考文献

原文地址:https://www.cnblogs.com/meiguhuaxian/p/14103064.html