Arman Feyzi
Arman Feyzi

Reputation: 838

how to disabled and enabled option item with jquery?

I have 4 select items in my form. When the user selects one item in any of selects, I want this item to be disabled in each other select element. My problem happens when I select all option items, because it disables everything. How can I to enabled/disabled the items when they are selected/deselect?

JsFiddle

First referee: <select class="d1">
  <option>One</option>  
  <option>Two</option> 
  <option>Three</option> 
  <option>Four</option> 
  <option>Five</option>  
  <option>Six</option> 
</select>
Second referee: <select class="d2">
  <option>One</option>  
  <option>Two</option> 
  <option>Three</option> 
  <option>Four</option> 
  <option>Five</option>  
  <option>Six</option> 
</select>

Third referee: <select class="d3">
  <option>One</option>  
  <option>Two</option> 
  <option>Three</option> 
  <option>Four</option> 
  <option>Five</option>  
  <option>Six</option> 
</select>
Fourth referee:<select class="d4">
  <option>One</option>  
  <option>Two</option> 
  <option>Three</option> 
  <option>Four</option> 
  <option>Five</option>  
  <option>Six</option> 
</select>


$(document).ready(function () {

    $('.d1, .d2, .d3, .d4').change(function () {
        var V1 = $('.d1').find(":selected").text();
        var V2 = $('.d2').find(":selected").text();
        var V3 = $('.d3').find(":selected").text();
        var V4 = $('.d4').find(":selected").text();

        $('.d1, .d2, .d3, .d4').children().each(function (index, element) {
            if ($(element).text() == V1 ) {
                $(this).prop('disabled', true);
            }
            if ($(element).text() == V2) {
                $(this).prop('disabled', true);
            }
            if ($(element).text() == V3) {
                $(this).prop('disabled', true);
            }
            if ($(element).text() == V4) {
                $(this).prop('disabled', true);
            }


        });
    });

});

Upvotes: 5

Views: 2867

Answers (8)

NandaIN
NandaIN

Reputation: 25

Try this may be this will work

$(document).ready(function () {

    $('.d1, .d2, .d3, .d4').change(function () {
        var V1 = $('.d1').find(":selected").text();
        var V2 = $('.d2').find(":selected").text();
        var V3 = $('.d3').find(":selected").text();
        var V4 = $('.d4').find(":selected").text();

        $('.d1, .d2, .d3, .d4').children().each(function (index, element) {
            if ($(element).text() == V1 ) {
                $(this).prop('disabled', true).siblings().removeAttr('disabled');;
            }
            if ($(element).text() == V2) {
                $(this).prop('disabled', true).siblings().removeAttr('disabled');;
            }
            if ($(element).text() == V3) {
                $(this).prop('disabled', true).siblings().removeAttr('disabled');;
            }
            if ($(element).text() == V4) {
                $(this).prop('disabled', true).siblings().removeAttr('disabled');;
            }


        });
    });

});

Upvotes: 0

giorgio
giorgio

Reputation: 10202

A lot of answers are already there (and good ones two), but I was busy creating my own version, so I'll post it anyway ;) I've made it a bit more flexible by selecting the select input by name, and the option by value.

HTML

First referee:
<select name="d1">
    <option value="1">One</option>
    <option value="2">Two</option>
    <!-- and so on -->
</select>

Second referee:
<select name="d2">
    <!-- same options here -->
</select>

<!-- even more dropdowns here -->

Javascript

The key here is to store the "old" value somewhere before it is changed, so you can re-enable the options on the other dropdowns.

$('select[name^="d"]').focus(function(){
    // Store the current value in the data attribute, for use later (whenever it's actually changed)
    $(this).data('previouslySelected', $(this).val());
}).change(function () {
    // Grab current (new) and old value (see focus event)
    var currentValue = $(this).val();
    var oldValue = $(this).data('previouslySelected');

    // Select all select inputs, but NOT the current one
    $('select[name^="d"]').not(this).each(function(i, e) {
        // disable currently selected
        var opt = $('option[value="' + currentValue + '"]', this).prop('disabled', true);
        // re-enable previously selected item
        $('option[value="' + oldValue + '"]', this).prop('disabled', false);
    });
});

And of course, here is the fiddle ;)

Upvotes: 0

charlietfl
charlietfl

Reputation: 171679

Here's a solution that instead of disabling the choices removes them instead. Subsequent changes will also be updated.

I added extra class ref_select to each element as well as value for each option

$(function () {
    var $ref_select = $('.ref_select');
    /* cache option html */
    var optHtml = $ref_select.first().html();

    $ref_select.on('change', function () {
        /* make array of all selected values*/
        var selecteds=$ref_select.find('option:selected').map(function(){               
               return this.value                
        }).get();
        /* rebuild the other select elements*/
        $ref_select.not(this).each(function(){
            var selVal=this.value || '';
            /* create new set of options with filtered values*/ 
            var $opts=$(optHtml).filter(function(){
                return $.inArray(this.value,selecteds) ==-1 ||  this.value ==selVal
            });
            /* replace children*/
           $(this).html($opts).val(selVal);

        });
    });
});

DEMO

Upvotes: 0

dartanian300
dartanian300

Reputation: 247

Try this script. It works by storing the index of the "previous" value on focus, and then sets that to be not disabled when looping through to disable the new one.

Keep in mind, using index will only work if all your options are in the same order.

jsFiddle

$(document).ready(function () {

    var origIndex;

    $('.d1, .d2, .d3, .d4').focus(function() {
        origIndex = $(this).find(":selected").index();
    }).change(function () {
        var index = $(this).find(":selected").index();

        $('.d1, .d2, .d3, .d4').each(function() {
            $(this).children().eq(index).prop("disabled", true);
            $(this).children().eq(origIndex).prop("disabled", false);
        });

    });

});

Upvotes: 0

billyonecan
billyonecan

Reputation: 20250

Set disabled to false on all <option> elements in the first line of your change handler. Then, loop over each <select> and disable any <option>s in sibling <select>s where this.value matches:

var $select = $('.d1, .d2, .d3, .d4');

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

    $select.find('option').prop('disabled', false);

    $select.each(function() {
        $(this).siblings('select').find('option')
               .filter('[value="' + this.value + '"]').prop('disabled', true);
    });

});

Here's a fiddle

Upvotes: 1

Karl-Andr&#233; Gagnon
Karl-Andr&#233; Gagnon

Reputation: 33870

If your select list are all the same you can base the disable on their index :

$(document).ready(function () {

    var $select = $('.d1, .d2, .d3, .d4').change(function () {
        $select.find('option').prop('disabled', false); //All option enabled
        $select.each(function(){
            var $this = $(this), index = $this.find(':selected').index(); //Get the index
            $select.not(this).find('option:nth-child('+ (index+1) +')').prop('disabled', true); //Select option base on their position and disable them


        })
    });

});

Fiddle : http://jsfiddle.net/u6eCL/16/

Else, here the code based on the text :

$(document).ready(function () {

    var $select = $('.d1, .d2, .d3, .d4').change(function () {
        $select.find('option').prop('disabled', false); //All option enabled
        $select.each(function(){
            var $this = $(this), text = $this.find(':selected').text(); //Get the text
            $select.not(this).find('option').filter(function(){
                return $(this).text() === text
            }).prop('disabled', true); //Select option base on their text and disable them


        })
    });

});

http://jsfiddle.net/u6eCL/15/

Upvotes: 2

boky
boky

Reputation: 835

Try with:

        $(this).attr('disabled', 'disabled');

instead of

        $(this).prop('disabled', true);

Upvotes: 0

T J
T J

Reputation: 43156

You can try the following as a quick fix

$(document).ready(function () {

$('.d1, .d2, .d3, .d4').change(function () {
    var V1 = $('.d1').find(":selected").text();
    var V2 = $('.d2').find(":selected").text();
    var V3 = $('.d3').find(":selected").text();
    var V4 = $('.d4').find(":selected").text();

    $('select option').prop('disabled',false); // reset everything

    $('.d1, .d2, .d3, .d4').children().each(function (index, element) {
        if ($(element).text() == V1) {
            $(this).prop('disabled', true);
        }
        if ($(element).text() == V2) {
            $(this).prop('disabled', true);
        }
        if ($(element).text() == V3) {
            $(this).prop('disabled', true);
        }
        if ($(element).text() == V4) {
            $(this).prop('disabled', true);
        }

    });
  });
});

Demo

Upvotes: 3

Related Questions