Ulle
Ulle

Reputation: 3

Disable / enable options on multiple selections according to their value / selected / not selected

Wished result:

The HTML:

<td class="formLabelHolder"><label for="field1174">Label</label></td>
<td class="formFieldHolder"><span><select name="field1" class="formSelect" id="field1">
<option selected="selected"></option>
<option>Large Format Solutions</option>
<option>Advanced Large Format Solutions</option>
<option>Scanning Solutions</option>
<option>Advanced Scanning Solutions</option>
<option>Office Imaging</option>
<option>Projectors Solutions</option>
</select>
</span></td>

I'm trying to solve this by using jQuery, and here's the code:

$(document).ready(function(){
    var select = $('#form-221 select :selected');


$('#form-221 select').change(function() {

        var value = $(this).val();
    var index = $('#form-221 select').index(this);


        $('#form-221 select option').each(function() {

    //  $(this).removeAttr('disabled');

            if ( $(this).val() == value ) {
                    $(this).attr('disabled', true);
            }
        if ( $(this).val() == select[index] ) {
                    $(this).attr('disabled', false);
            }
            });

//  console.log($(':selected', select.parent('select')[index]).val());  

    select = $('#form-221 select :selected');

    });
});

I also tried this:

 $(document).ready(function(){



$('#form-221 select').change(function() {

        var value = $(this).val();



        $('#form-221 select option').each(function() {

        $(this).removeAttr('disabled');

            if ( $(this).val() == value ) {
                    $(this).attr('disabled', true);
            }

            });
    });
});

But it results in only following the last changed selection.

The upper code works (if you take away the first "if") half way, it disables the selections alright, but when changing a selection it doesn't enable it.

I must be doing something wrong and I'm trying to figure this out as we speak ;) If I do find the answer I'll paste it here as well :)

If someone has another way of approaching this please let me know! I'm eager to find the answer / solution :)

I found another question about something like this, but it only works for 2 selections, I tried ;)

Upvotes: 0

Views: 7619

Answers (2)

mekwall
mekwall

Reputation: 28974

After some fiddling on jsFiddle I ended up with this:

var selects = $("select"),
    options = selects.find("option");

selects.change(function(){
    options.removeAttr("disabled");
    selects.each(function(){
        var idx = $(this).find("option:selected").index(),
            otherSelects = selects.not(this);
        if (idx != null) {
            otherSelects.find("option:eq("+idx+")").attr("disabled", "disabled");
        }
    });
});

I tried with the :contains selector as well, but didn't work as expected. The above uses indexes instead, and works as long as the options are in the same order (i.e. have the same index) within the select element.

I'd recommend to set a unique value attribute (internal id perhaps?) for each option and select based on that. Then it doesn't matter in which order they are within the select element.

Note that even though the disabled attribute for the option element is specified in the HTML4/5 specifications, all IE versions before 8 lack support. Reference: MSDN and Dottoro

Upvotes: 1

Simon
Simon

Reputation: 3539

One Solution would be to save all selected values in an array on each change and then check for each available option if its value is stored in this array:

$('select').change(function() {

  var selections = [];
  $('select option:selected').each(function(){
    if($(this).val())
        selections.push($(this).val());
  })
  $('select option').each(function() {
     $(this).attr('disabled', $.inArray($(this).val(),selections)>-1 && !$(this).is(":selected"));
  });
});

See an example here: http://jsfiddle.net/398Sj/

Upvotes: 3

Related Questions