0

I need to make sure that when a value is selected in one of the lists, it cannot be selected in any of the others. Can this be done with jQuery, or do I need to create a validator that does not allow selection of the same value?

I have multiple select lists which are basically numbers only, i.e.

  <select id="101_1">
  <option value="0">0</option>
  <option value="1"> 1</option>
  <option value="2"> 2</option>
  <option value="3"> 3</option>
  <option value="4"> 4</option>
  <option value="5"> 5</option>
  <option value="6"> 6</option>
  <option value="7"> 7</option>
  ....
  <option value="50"> 50</option>
 </select>

 <select id="101_2">
 <option value="0">0</option>
 <option value="1"> 1</option>
 <option value="2"> 2</option>
 <option value="3"> 3</option>
 <option value="4"> 4</option>
 <option value="5"> 5</option>
 <option value="6"> 6</option>
 <option value="7"> 7</option>
  ....
  <option value="50"> 50</option>
 </select>

 <select id="101_1">
  <option value="0">0</option>
  <option value="1"> 1</option>
  <option value="2"> 2</option>
  <option value="3"> 3</option>
  <option value="4"> 4</option>
  <option value="5"> 5</option>
  <option value="6"> 6</option>
  <option value="7"> 7</option>
  ....
  <option value="50"> 50</option>
 </select>
RayfenWindspear
  • 6,116
  • 1
  • 30
  • 42
Pranav Shah
  • 91
  • 1
  • 2
  • 12
  • @pedrolobito i am quite new to this and dont know where to start so was following this http://stackoverflow.com/questions/1280499/jquery-set-select-index – Pranav Shah May 14 '16 at 04:14

2 Answers2

2

I have gotten the following code to work for one of my colleagues :

HTML :

<h3>List 1</h3>
<select id="select1">
  <option value="null">-- select --</option>
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
  <option value="E">E</option>
</select>

<h3>List 2</h3>
<select id="select2">
  <option value="null">-- select --</option>
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
  <option value="E">E</option>
</select>

<h3>List 3</h3>
<select id="select3">
  <option value="null">-- select --</option>
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
  <option value="E">E</option>
</select>

JS with jQuery :

$(document).ready(function() {
  var selectState = {
    'select1': 'null',
    'select2': 'null',
    'select3': 'null'
  };

  $('select').change(function() {
    var selectId = $(this).attr('id');
    var selectedOptionValue = $(this).val();

    // for each other select element
    $('select[id!="' + selectId + '"]').each(function(index) {
      // enable the old option
      $(this).find('option[value="' + selectState[selectId] + '"]').removeAttr('disabled');

      if (selectedOptionValue !== 'null') { // if selected a real option
        // disable the new option
        $(this).find('option[value="' + selectedOptionValue + '"]').attr('disabled', 'disabled');
      }
    });

    selectState[selectId] = selectedOptionValue; // update the new state at the end
  });
});

And here is a CodePen

Bryan Lee
  • 150
  • 1
  • 8
1

I opted to hide the option tag instead of remove as I suggested. Here is a complete working html file. I was going to post it on jsfiddle, but for some reason it wouldn't work. Be very aware of copy/paste errors in the .change handlers. Spent some time myself wondering why it wasn't working, but it was a copy/paste error.

Note that this code only works if every select tag has the same options. But, it works dynamically if you add or remove options later, while keeping them in sync as noted.

If you need it to work with lists with only some of the same options, you will be stuck dealing with having IDs on the options and then working the hiding/unhiding based on that instead of indexing into the children, but the basic mechanics are the same.

<!DOCTYPE html>
<html>
<head>
    <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
    <style type="text/css">
        .gone {display: none;}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            // hides the option selected in the others
            var hideValue = function(oldval, val, options, others) {

                var unhideChild = -1;
                var hideChild = -1;
                // find which child to hide in the others
                // also find the value we change from and unhide it
                for (var i=1; i<options.length; i++) {
                    var optval = $(options[i]).val();
                    console.log(optval);
                    if (optval == val) {
                        hideChild = i;
                    }
                    if (optval == oldval) {
                        unhideChild = i;
                    }
                }
                if (unhideChild == -1 && oldval != "None") {
                    console.log("uh oh");
                    return;
                }
                if (hideChild == -1 && val != "None") {
                    console.log("uh oh");
                    return;
                }

                // hide them using the passed in selectors
                for (var j=0; j<others.length; j++) {
                    if (oldval != "None") {
                        console.log("unhiding: " + others[j] + " v: " + unhideChild);
                        $($(others[j]).children()[unhideChild]).removeClass("gone");
                    }
                    if (val != "None") {
                        console.log("hiding: " + others[j] + " v: " + hideChild);
                        $($(others[j]).children()[hideChild]).addClass("gone");
                    }
                }
            }

            // we need to keep track of the old values so we can unhide them if deselected
            var val1 = "None";
            var val2 = "None";
            var val3 = "None"

            $('#101_1').change(function() {
                var opts = $('#101_1').children();
                var v = $('#101_1').val();
                hideValue(val1, v, opts, ["#101_2", "#101_3"]);
                val1 = v;
            });
            $('#101_2').change(function() {
                var opts = $('#101_2').children();
                var v = $('#101_2').val();
                hideValue(val2, v, opts, ["#101_1", "#101_3"]);
                val2 = v;
            });
            $('#101_3').change(function() {
                var opts = $('#101_3').children();
                var v = $('#101_3').val();
                hideValue(val3, v, opts, ["#101_2", "#101_1"]);
                val3 = v;
            });
        });
    </script>
</head>
<body>

    <select value="None" id="101_1">
        <option value="None">None</option>
        <option value="0">0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <select value="None" id="101_2">
        <option value="None">None</option>
        <option value="0">0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <select value="None" id="101_3">
        <option value="None">None</option>
        <option value="0">0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
</body>
</html>

Also, if you need the "None" value to not be there, remove it. Then just start the select ta 101_1 having 0 selected, 101_2 with 1 selected etc. Then make sure to trigger the change handler. Also, without the None option, the for loop needs to start with i=0.

So basically add this to the end of the script and make sure var i starts at 0 instead of 1.

$('#101_1').val('0');
$('#101_2').val('1');
$('#101_3').val('2');
$('#101_1').trigger('change');
$('#101_2').trigger('change');
$('#101_3').trigger('change');
RayfenWindspear
  • 6,116
  • 1
  • 30
  • 42
  • yes indeed i wanted this...do you have any link which i can follow to create same. – Pranav Shah May 14 '16 at 05:53
  • Note that it is not necessary to check if any of the values are the same. It shouldn't be possible for any of them to end up with the same value (except the "None" special case). If you are worried about it though, it would be easy to add a check for it and reset one of them if it happens. – RayfenWindspear May 16 '16 at 17:34
  • Great its working awesome :) Thank you for response and kind guidance. – Pranav Shah May 16 '16 at 18:17
  • No problem. I will now edit your question so others will understand better. It took me a wrong answer and a few reads to figure out what you needed. – RayfenWindspear May 16 '16 at 18:23