【问题标题】:How to disable multiple options in a select based on another select in JavaScript / Jquery如何基于 JavaScript / Jquery 中的另一个选择禁用选择中的多个选项
【发布时间】:2020-03-09 14:21:02
【问题描述】:

我正在使用Select2 Jquery 插件。我必须选择 2 个 tableHeadertableBody ,我可以在其中选择多个标签。 我想做的是:

  • 如果我在第一次选择时选择了一个或多个选项/它们将在第二次选择中被禁用,反之亦然,如果我从一个选择中取消选择一个选项,它将在另一个选择中启用。

我所做的是:

我创建了一个数组selections,我在其中存储从第一次选择中选择的选项,然后我循环通过第二次选择的选项并检查该值是否存在于数组中然后禁用它。

我猜逻辑应该是正确的。只是无法找出为什么我的选项没有被禁用。请问有什么建议吗?

这是我的解释代码。

$(document).ready(function() { 
    
    // this function to search and show matched input
    function matchCustom(params, data) {

    if ($.trim(params.term) === '') { return data; }

    if (typeof data.text === 'undefined') { return null; }

    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
      var modifiedData = $.extend({}, data, true);
      modifiedData.text += '';
     return modifiedData; }

    return null; }

  $(".select2").select2({
  matcher: matchCustom
  });

//if you select or unselect option trigger this
$('#tableHeader').change(function() {

    var selections = [];
    // if you select an option then add the value in array
   $('#tableHeader').on('select2:select', function (e) { 
    
      $('#tableHeader option:selected').each(function(){
        if($(this).val())
            selections.push($(this).val());  });
     
     });
     // if you unselect an option then remove from array
   $('#tableHeader').on('select2:unselect', function (e) {
      var unselected = e.params.data.id;
      selections.splice( $.inArray(unselected, selections), 1 );

    }); 
     
      console.log(selections);

     // loop through other select option and check if value exists in array then disable it
     $('#tableBody option').each(function() {
       if(jQuery.inArray($(this).val(), selections) !== -1) {  
       console.log($(this).val());
      $('#tableBody option[value="'+ $(this).val() + '"]').prop('disabled',true); }

      });
      
     

    });
    
    // do the same if you start with second select 
    $('#tableBody').change(function() {

    var selections = [];
    
   $('#tableBody').on('select2:select', function (e) { 
    
      $('#tableBody option:selected').each(function(){
        if($(this).val())
            selections.push($(this).val());  });
     
     });
     
   $('#tableBody').on('select2:unselect', function (e) {
      var unselected = e.params.data.id;
      selections.splice( $.inArray(unselected, selections), 1 );

    }); 
     
      console.log(selections);

     $('#tableHeader option').each(function() {
       if(jQuery.inArray($(this).val(), selections) !== -1) {  
       console.log($(this).val());
      $('#tableHeader option[value="'+ $(this).val() + '"]').prop('disabled',true); }

      });
      
     

    });

});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>

<span>Table Header</span>
<select id="tableHeader" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">      
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>              
</select>
<br>
<span>Table Body</span>
<select id="tableBody" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">      
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>              
</select>

【问题讨论】:

  • 我首先看到的是,您可以优化您的代码,例如 var $tableHeader = $('#tableHeader') 并改用该变量。我猜第一个更改事件也将包含有关所选项目的信息,不需要嵌套的 on 子句...这不是您问题的答案,但可以帮助使代码更具可读性

标签: javascript html jquery css jquery-select2


【解决方案1】:

你的逻辑虽然是正确的,但我认为你只是在为自己复杂化。只需每次更改每个选择的值,循环另一个选择并逐个禁用具有相同值的选择。

$(document).ready(function() {

  // this function to search and show matched input
  function matchCustom(params, data) {

    if ($.trim(params.term) === '') {
      return data;
    }

    if (typeof data.text === 'undefined') {
      return null;
    }

    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
      var modifiedData = $.extend({}, data, true);
      modifiedData.text += '';
      return modifiedData;
    }

    return null;
  }

  $(".select2").select2({
    matcher: matchCustom
  });

  $('#tableHeader').change(function() {

    var tableHeader = $(this).val();
    var tableBody = $("#tableBody")[0];

    $.each(tableBody.options, function(i, item) {
      if (tableHeader.includes(item.value)) {
        $(item).prop("disabled", true);
      } else {
        $(item).prop("disabled", false);
      }
    });

  });

  $('#tableBody').change(function() {

    var tableBody = $(this).val();
    var tableHeader = $("#tableHeader")[0];

    $.each(tableHeader.options, function(i, item) {
      if (tableBody.includes(item.value)) {
        $(item).prop("disabled", true);
      } else {
        $(item).prop("disabled", false);
      }
    });

  });

});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>

<span>Table Header</span>
<select id="tableHeader" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">
  <option value="Geo">Geo</option>
  <option value="Region">Region</option>
  <option value="Country">Country</option>
  <option value="Order Numer">Order Numer</option>
  <option value="Order Value">Order Value</option>
  <option value="Brand">Brand</option>
  <option value="Quantity">Quantity</option>
  <option value="Price">Price</option>
  <option value="Revenue">Revenue</option>
  <option value="Currency">Currency</option>
  <option value="Created Date">Created Date</option>
  <option value="Created By">Created By</option>
</select>
<br>
<span>Table Body</span>
<select id="tableBody" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">
  <option value="Geo">Geo</option>
  <option value="Region">Region</option>
  <option value="Country">Country</option>
  <option value="Order Numer">Order Numer</option>
  <option value="Order Value">Order Value</option>
  <option value="Brand">Brand</option>
  <option value="Quantity">Quantity</option>
  <option value="Price">Price</option>
  <option value="Revenue">Revenue</option>
  <option value="Currency">Currency</option>
  <option value="Created Date">Created Date</option>
  <option value="Created By">Created By</option>
</select>

【讨论】:

  • 非常感谢。正是我需要的:)
【解决方案2】:

只需启用和禁用彼此的更改事件,请参见下面的片段

$(document).ready(function() { 
    
        // this function to search and show matched input
    function matchCustom(params, data) {

    if ($.trim(params.term) === '') { return data; }

    if (typeof data.text === 'undefined') { return null; }

    if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
      var modifiedData = $.extend({}, data, true);
      modifiedData.text += '';
     return modifiedData; }

    return null; }

  $(".select2").select2({
  matcher: matchCustom
  });
    
    var disableTableBody = function(value){
           $('#tableBody option[value="'+ value +'"]').prop('disabled',true);
    };
    
    var enableTableBody = function(value){
       $('#tableBody option[value="'+ value +'"]').prop('disabled',false);
    };
    
       var disableTableHeader = function(value){
           $('#tableHeader option[value="'+ value +'"]').prop('disabled',true);
    };
    
    var enableTableHeader = function(value){
       $('#tableHeader option[value="'+ value +'"]').prop('disabled',false);
    };
    
    
   $("#tableHeader").change(function(){
		  	   disableTableBody($(this).val());  
   });
   
   $('#tableHeader').on("select2:unselecting", function(e){
   			enableTableBody($(this).val());
   });

   $("#tableBody").change(function(){
		  	   disableTableHeader($(this).val());  
   });
   
   $('#tableBody').on("select2:unselecting", function(e){
   			enableTableHeader($(this).val());
   });

});
   
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>

<span>Table Header</span>
<select id="tableHeader" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">      
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>              
</select>
<br>
<span>Table Body</span>
<select id="tableBody" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">      
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>              
</select>

【讨论】:

  • 感谢您的尝试,但它不起作用。我做了类似的方法,它只禁用你选择的第一个标签,其余的都没有禁用。您可以通过运行代码并选择多个选项来验证这一点。您将只有第一选择禁用,其余没有。
猜你喜欢
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2012-01-30
  • 2016-10-06
  • 2011-11-09
  • 1970-01-01
相关资源
最近更新 更多