【问题标题】:multiple select boxes with same options - require unique selection具有相同选项的多个选择框 - 需要唯一选择
【发布时间】:2018-06-15 00:34:46
【问题描述】:

我有一个带有 3 个选择框的表单。每个选择框都有相同的选项。我想要求您必须为每个选择框选择不同的选项。例如,假设选项是“cat”、“dog”和“bird”。如果有人在第一个选择框中选择“鸟”,我想从其他两个框中禁用或隐藏该选项。如果他们更改选择,则“鸟”将再次启用或取消隐藏。

<select id="box1">
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="bird">Bird</option>
</select>

<select id="box2">
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="bird">Bird</option>
</select>

<select id="box3">
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="bird">Bird</option>
</select>

我假设我可以使用 jquery onchange 做到这一点,但我不确定如何要求跨不同选择框的唯一选择。

$('select').on('change', function() {
    // If option is selected, disable it in all other select boxes. If option is deselected, reenable it in all other select boxes.
})

感谢您的帮助!

【问题讨论】:

    标签: javascript jquery forms


    【解决方案1】:

    1) 自上而下的优先方法

    流程必须从上到下。这也意味着当用户更改下拉列表值时,必须重置所有下一个下拉列表。说了这么多,这是我的代码sn-p。

    HandleDropdowns($('#box1'));  //initially call this function to handle the dropdowns by passing the first dropdown as parameter
     
    $('select').on('change', function() {
      HandleDropdowns($(this)); // handle all dropdowns on any change event.
    });
    
    function HandleDropdowns(element) {      
      var $element = element;
      var value = $element.val();
    
      $element.nextAll().val('');  //using nextAll lets reset all the following dropdowns
      $element.nextAll().attr('disabled', 'disabled'); //disable all the following dropdowns.
      HandleOptions(); // call this function to toggle the options 
    
      if (value.length) {
        $element.next().removeAttr('disabled'); // only if this dropdown has some selection enable the next dropdown.
      }
    }
    
    function HandleOptions() {
      $('option').removeAttr('disabled'); //reset all the options to be available
      $.each($('select'), function() { //loop from top to bottom and disable the options one by one.
        var value = $(this).val();
        if (value.length) {
          $(this).nextAll().find('option[value="' + value + '"]').attr('disabled', 'disabled');
        }
      });
    
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <select id="box1">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>
    
    <select id="box2">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>
    
    <select id="box3">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>

    2) 具有相同优先级方法的所有选择框

    在这种方法中,当用户选择一个值时,我们会检查是否有其他下拉菜单具有相同的值,如果是则重置它,否则什么也不做。下面是一个工作示例。

    $('select').on('change', function() {
      HandleDropdowns($(this));
    });
    
    function HandleDropdowns(element) {
      var $element = element;
      var value = $element.val();
      
      $.each($('select').not($element), function() { //loop all remaining select elements
        var subValue = $(this).val();
        if (subValue === value) { // if value is same reset
          $(this).val('');
          console.log('resetting ' + $(this).attr('id')); // demo purpose
        }
      });  
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <select id="box1">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>
    
    <select id="box2">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>
    
    <select id="box3">
      <option value="">Select</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="bird">Bird</option>
    </select>

    【讨论】:

    • 谢谢。这似乎是最好的答案。但是当您返回并更改第一个选择时,它是否必须重置所有内容?有没有办法只重置你没有选择的选项?
    • @LBF 会再次引入复杂性。例如,如果第一个下拉列表是猫,第二个是狗,第三个是鸟..现在如果我继续并首先选择狗,这意味着我需要清除第二个下拉列表。这意味着第三个仍然选择了鸟,但是现在有可能我可以在第二个下拉列表中选择鸟,这意味着我必须清除第三个..这就是我建议在一个下拉列表中重置以下下拉列表的原因下拉更改值。
    • @LBF 或者您是否正在寻找一种非自上而下的解决方案。而是对所有下拉菜单给予相同的优先级?
    • 是的,我正在寻找一种对所有下拉菜单给予相同优先级的解决方案。我想@Melvin 的答案采用了这种方法,但是当您尝试更改答案时它无法正常工作。嗯……
    • @LBF 根据您的要求添加了不同的方法。
    【解决方案2】:

    试试这个

    $('select').on('change', function () {
      $("select").find("option").removeAttr("disabled");
      $("select").not(this).find("option[value=" + $(this).val() + "]").attr("disabled", "disabled");
    });
    

    【讨论】:

    • @Downvoters 请解释原因,以便我将来更正。
    • 此代码不一致..当我在最后一个 select 元素中选择最后一个剩余选项时会发生什么情况,前两个元素现在仅禁用此选项,而其他两个选项已启用两个下拉菜单。这意味着现在在第二个下拉列表中我可以选择与第一个下拉列表相同的值
    【解决方案3】:

    您可以使用 onchange 监听器并同时评估结果。还添加一个重置按钮,因为一旦选择了三个,它就会变成瓶颈。

    工作代码如下

    function changeSelect(elements) {
      var values = {};
      elements.forEach(function(item){
        values[item.id] = item.value;
      });
      elements.forEach(function(item){
        for(var i = 0; i < item.children.length; i++) {
          for(ids in values) {
            if(item.id != ids && item.children[i].value == values[ids]) {
              item.children[i].style.display = 'none';
            }
          }
        }
      });
    }
    
    function resetSelection(elements) {
      elements.forEach(function(item){
        item.value = '';
        for(var i = 0; i < item.children.length; i++) {
          item.children[i].style.display = '';
        }
      });
    }
    
    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    var box3 = document.getElementById('box3');
    var boxArray = [box1, box2, box3];
    boxArray.forEach(function(item){
      item.addEventListener('change', changeSelect.bind(undefined,boxArray));
    });
    document.getElementById('reset').addEventListener('click', resetSelection.bind(undefined,boxArray));
    <select id="box1">
        <option value="">Select An Option</option>
        <option value="cat">Cat</option>
        <option value="dog">Dog</option>
        <option value="bird">Bird</option>
    </select>
    
    <select id="box2">
        <option value="">Select An Option</option>
        <option value="cat">Cat</option>
        <option value="dog">Dog</option>
        <option value="bird">Bird</option>
    </select>
    
    <select id="box3">
        <option value="">Select An Option</option>
        <option value="cat">Cat</option>
        <option value="dog">Dog</option>
        <option value="bird">Bird</option>
    </select>
    <button id="reset">Reset</button>

    【讨论】:

    • 谢谢。我希望找到一种无需重置按钮的方法,但我理解为什么它是必要的。如果您尝试返回并更改答案而没有注意到您必须重置,这会有点令人困惑。
    猜你喜欢
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    • 2018-03-31
    相关资源
    最近更新 更多