【问题标题】:Disable options based on previous selects禁用基于先前选择的选项
【发布时间】:2014-07-23 11:58:16
【问题描述】:

我有四个<select> 标签。它们如下:

<select name="" id="a">
    <option value="0">Select</option>
    <option value="1">Milk</option>
    <option value="2">Eggs</option>
    <option value="3">Cheese</option>
    <option value="4">Butter</option>
    <option value="5">Pizza</option>
</select>
<select name="" id="b">
    <option value="0">Select</option>
    <option value="1">Milk</option>
    <option value="2">Eggs</option>
    <option value="3">Cheese</option>
    <option value="4">Butter</option>
    <option value="5">Pizza</option>
</select>
<select name="" id="c">
    <option value="0">Select</option>
    <option value="1">Milk</option>
    <option value="2">Eggs</option>
    <option value="3">Cheese</option>
    <option value="4">Butter</option>
    <option value="5">Pizza</option>
</select>
<select name="" id="d">
    <option value="0">Select</option>
    <option value="1">Milk</option>
    <option value="2">Eggs</option>
    <option value="3">Cheese</option>
    <option value="4">Butter</option>
    <option value="5">Pizza</option>
</select>

这四个应该有独特的选择,尽管他们有相同的项目集。那么使用 jQuery,我如何禁用已经选择的选项?准确地说,我需要从&lt;select&gt; 标记中获取四个值。

解决方案和问题

当前的问题有一个解决方案,但它有一个限制。检查我的答案以获得解决方案。

此解决方案不可扩展。如果有四个&lt;select&gt;s,则应该有四个变量,并且手动制作它们的过程很繁琐。期待更好的解决方案。

【问题讨论】:

    标签: jquery select chained-select


    【解决方案1】:

    每次选择更改时,只需遍历每个选择,然后在值匹配的所有其他选择中禁用该选项:

    $('select').on('change', function() {
    
        /* enable any previously disabled options */
        $('option[disabled]').prop('disabled', false);
    
        /* loop over each select */
        $('select').each(function() {
    
           /* for every other select, disable option which matches this this.value */
           $('select').not(this).find('option[value="' + this.value + '"]').prop('disabled', true); 
    
        });
    
    });
    

    Here's a fiddle

    【讨论】:

      【解决方案2】:

      如果我有一组已知的有限数据,比如我在这里有四个选项,我可以这样做。

      伪代码

      1. 禁用所有&lt;select&gt; 标签并仅启用第一个标签。
      2. &lt;select&gt; 发生变化时,启用下一个&lt;select&gt;,并禁用当前&lt;select&gt; 值的选项。
      3. 将当前&lt;select&gt; 的值保存到适当的变量中。
      4. 更改下一个&lt;select&gt; 时,禁用前一个&lt;select&gt;,以免更改所选选项。
      5. 其余部分重复此操作,增加值的数量。

      jQuery 代码

      $(document).ready(function(){
          var a, b, c, d;
          $("#b, #c, #d").prop("disabled", true);
          $("#a").change(function(){
              a = $(this).val();
              $("#b").find('option[value="' + a + '"]').prop("disabled", true);
              $("#b").prop("disabled", false);
          });
          $("#b").change(function(){
              b = $(this).val();
              $("#a").prop("disabled", true);
              $("#c").find('option[value="' + a + '"]').prop("disabled", true);
              $("#c").find('option[value="' + b + '"]').prop("disabled", true);
              $("#c").prop("disabled", false);
          });
          $("#c").change(function(){
              c = $(this).val();
              $("#a").prop("disabled", true);
              $("#b").prop("disabled", true);
              $("#d").find('option[value="' + a + '"]').prop("disabled", true);
              $("#d").find('option[value="' + b + '"]').prop("disabled", true);
              $("#d").find('option[value="' + c + '"]').prop("disabled", true);
              $("#d").prop("disabled", false);
          });
          $("#d").change(function(){
              d = $(this).val();
              $("#a").prop("disabled", true);
              $("#b").prop("disabled", true);
              $("#c").prop("disabled", true);
          });
          $("#reset").click(function(){
              $("#a").prop("disabled", false);
              $("#b, #c, #d").prop("disabled", true);
              $("#a, #b, #c, #d").val(0);
              return false;
          });
      });
      

      这个解决方案的问题:

      此解决方案不可扩展。如果有四个&lt;select&gt;s,则应该有四个变量,并且手动制作它们的过程很繁琐。期待更好的解决方案。

      小提琴:http://jsfiddle.net/praveenscience/D5ZSk/

      【讨论】:

        【解决方案3】:

        不确定我是否完全理解您的问题,但您可以这样做:

        HTML

        <select>
            <option value="0">Select</option>
            <option value="1">Milk</option>
            <option value="2">Eggs</option>
            <option value="3">Cheese</option>
            <option value="4">Butter</option>
            <option value="5">Pizza</option>
        </select>
        <select>
            <option value="0">Select</option>
            <option value="1">Milk</option>
            <option value="2">Eggs</option>
            <option value="3">Cheese</option>
            <option value="4">Butter</option>
            <option value="5">Pizza</option>
        </select>
        <select>
            <option value="0">Select</option>
            <option value="1">Milk</option>
            <option value="2">Eggs</option>
            <option value="3">Cheese</option>
            <option value="4">Butter</option>
            <option value="5">Pizza</option>
        </select>
        

        JS

        $(document).ready(function () {
            $("select").on("change", function () {
                // Enable all options
                $("option").prop("disabled", false);
        
                // Get an array of all current selections
                var selected = [];
                $("select").each(function () {
                    selected.push($(this).val());
                });
        
                // Disable all selected options, except the current showing one, from all selects
                $("select").each(function () {
                    for (var i = 0; i < selected.length; i++) {
                        if (selected[i] != $(this).val()) {
                            $(this).find("option[value='" + selected[i] + "']").prop("disabled", true);
                        }
                    }
                });
            });
        });
        

        您所做的是将选定的选项保存在一个数组中,并在另一个 selects 中禁用这些选定的选项。

        请参阅此 FIDDLE 示例。

        【讨论】:

        • 是的,这看起来是可扩展的! :)
        • 是的!无论您有多少选择,它都会起作用。当然,如果您的选择多于选项,您将获得一些选择而没有任何可用选项;)
        • 看起来不错... :) 等待更多答案,如果没有比这更好的了,我会接受。你检查我的答案了吗?
        【解决方案4】:

        这是您真正需要数据模型的地方。在幕后,您只需拥有一个对象,其中包含项目列表和是否选择项目的布尔值。然后,每个选项列表将绑定到该列表。如果项目的布尔值为 false,则每个项目只会在其列表中显示该项目。

        var allItems = [{item:"eggs",isSelected:false}, 
              {item:"pizza",isSelected:false},
              {item:"cheese",isSelected:false},
              {item:"milk",isSelected:false} ];
        

        所有选项控件都与该列表相关联。 当将项目加载到选项控件中时,有 javascript 检查每个值以查看 isSelected 是否为 false。只有当它为 false 时,选项控件才会在其列表中显示该项目。

        这在 Angular 中会容易得多。

        【讨论】:

        • 哇...好技术..没想到会这样!
        • 很高兴你喜欢。它确实让这一切变得更容易,因为你只需要在一个地方管理代码:allItems 数组。
        • @daylight 这个问题是你不知道哪个值属于哪个选择,所以你最终会在每个选择中禁用当前选择的选项
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 2012-06-11
        • 1970-01-01
        相关资源
        最近更新 更多