Disable options based on previous selects

我们两清 提交于 2019-12-12 12:31:35

问题


I have four <select> tags. They are as follows:

<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>

These four are supposed to be having unique selections, although they have the same set of items. So using jQuery, how do I disable the options that are already selected? To be precise, I need to have four values taken from the <select> tag.

Solution and Problem

The current problem has a solution, but there's a limitation in it. Check my answer for the solution.

This solution is not scalable. If there are four <select>s, there should be four variables and the manual process to make them is tedious. Expecting a better solution.


回答1:


Each time a select changes, just loop over each one, and then disable the option in all other selects where the value matches:

$('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:


If I have a known limited set of data, like I have four options here, I can do this way.

Pseudo Code

  1. Disable all the <select> tags and enable only the first.
  2. When a <select> is changed, enable the next <select>, and disable the option of the current <select>'s value.
  3. Save the current <select>'s value to the appropriate variable.
  4. When the next <select> is changed, disable the previous <select>, in order not to change the option selected.
  5. Repeat it for the rest, with increased number of values.

jQuery Code

$(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;
    });
});

Problem with this Solution:

This solution is not scalable. If there are four <select>s, there should be four variables and the manual process to make them is tedious. Expecting a better solution.

Fiddle: http://jsfiddle.net/praveenscience/D5ZSk/




回答3:


Not sure I fully understand your question, but you could do something like this:

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);
                }
            }
        });
    });
});

What you do is save the selected options in an array and disable these selected options in the other selects.

See this FIDDLE for an example.




回答4:


This is where you really need a model for the data. Behind the scenes you would simply have an object which contains the list of items and a bool for whether or not the item was selected. Then, each option list would be tied to that list. Each one would only display the item in its list if the item's bool value was false.

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

All of the options controls are tied to that one list. When loading the items into the options control there is javascript which checks each value to see if isSelected is false. Only if it is false does the option control show the item in its list.

This would be much easier in Angular.



来源:https://stackoverflow.com/questions/24909907/disable-options-based-on-previous-selects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!