haakym
haakym

Reputation: 12358

Disable select option in group of select dropdowns when option is selected

What I'm trying to do: I have multiple select dropdowns, if an option is selected in one of the select dropdowns and the value exists in any of the other dropdowns the value should be disabled/unselectable, it again can become enabled/selectable if the selection is changed.

What happens with current code: it works about 50%, I can't pinpoint the issue, but I think because I'm applying a for loop some values get skipped and not disabled and sometimes the "Select" default option becomes disabled?!

Approach: The way I wrote my code was when a selection from the dropdown box occurs, enable all options, get the first dropdown's current selected value, if it's not the default "Select" then go through every dropdown box and disable any matching values, then repeat this process for the second dropdown's current selected value and so on.

Fiddle: http://jsfiddle.net/haakym/r2y73ndt/

Code: HTML:

<div id="nomineeInfo">
<div>
    <label>Manager</label>
    <select class="positionTypes" id="pos_manager">
        <option value="0">Select</option>
        <option value="1">John Smith</option>
        <option value="2">Jane Smith</option>
        <option value="4">John Smoe</option>
    </select>
</div>
<div>
    <label>Deputy</label>
    <select class="positionTypes" id="pos_deputy_manager">
        <option value="0">Select</option>
        <option value="1">John Smith</option>
        <option value="2">Jane Smith</option>
        <option value="3">John Doe</option>
    </select>
</div>
<div>
    <label>Finance</label>
    <select class="positionTypes" id="pos_finance">
        <option value="0">Select</option>
        <option value="1">John Smith</option>
        <option value="3">John Doe</option>
        <option value="4">John Smoe</option>
    </select>
</div>

Javascript:

$('#nomineeInfo').on('change', '.positionTypes', function () {
    var selectedValue = $(this).val();
    var dropdownOnChangeId = $(this).prop('id');
    var positionTypesEn = ['manager', 'deputy_manager', 'finance'];

    // set all enabled
    for (var i = 0; i < 7; i++) {
        $('#pos_'+positionTypesEn[i]).each(function(){
            $("option", this).removeAttr('disabled');
        });
    };

    for (var i = 0; i < 7; i++) {
        // if position type selected value is not 0, i.e. if it's not "Select"
        if( $('#pos_' + positionTypesEn[i]).val() != 0 ){
            // go through each option in every dropdown
            for (var j = 0; j < 7; j++) {
                console.log( positionTypesEn[j] ); // show current dropdown
                $('#pos_' + positionTypesEn[j] + ' option').each(function(k){

                    if( !$(this).is(':selected') ){ 
                        if( $(this).val() == selectedValue && $(this).val() != 0 ){
                            $(this).prop('disabled', 'true');
                            console.log('disabled: ' +  $(this).val() );
                        }
                    }
                });
            }
        }
    }
});

Any help is much appreciated!

Upvotes: 1

Views: 4560

Answers (4)

Balachandran
Balachandran

Reputation: 9637

Try this too, an optimized version

$("select.positionTypes").change(function () {
    $("select.positionTypes option[value='" + $(this).data('index') + "']").prop('disabled', false);
    $(this).data('index', this.value);
    $("select.positionTypes option[value='" + this.value + "']:not([value='0'])").prop('disabled', true);
});

DEMO

Upvotes: 1

Balachandran
Balachandran

Reputation: 9637

try

$("select.positionTypes").change(function () {
    $("select.positionTypes option").prop('disabled', false);
    $("select.positionTypes option:selected:not([value='0'])").each(function (i) {
        $("select.positionTypes option:nth-child(" + ((+this.value) + 1) + ")").prop('disabled', true)
    });
});

DEMO

Upvotes: 1

Steini
Steini

Reputation: 2783

Your html structure, classes and attempt is not bad but if you are using jQuery you should use its full advantages like .each function to make your live alot easier.

I would make an attempt like this:

$('.positionTypes').on('change', function () { //When any select changes...
    var changedID = $(this).attr("id"); //Save id of select that was changed...
    var selectedValue = $(this).val(); //Save value of select was changed...
    if($(this).val() != "0") { //If we did not select a 0 value at all...
        $('.positionTypes option').prop("disabled", false); //Enable all disabled options of all selects...
        $('.positionTypes').each(function() { //Loop all existing selects
            if($(this).attr("id") != changedID) { //If the select id is not our own select
                $("#" + $(this).attr("id") + " option").each(function() { //loop all options of all selects except the one excluded by previous if clause
                    if($(this).attr("value") == selectedValue) { //if the value matches to saved value
                        $(this).prop("disabled", true); //Disable this one
                    }
                });
            }
        });
    };
});

I am not sure if this is 100% complete atleast it can disable options of other selects with identical value with a little bit more structured code.

Upvotes: 0

Barmar
Barmar

Reputation: 781058

After enabling all the options, you need to go through all the menus, get their selected values, and re-disable all of them in the other menus, not just the one you just changed.

$(document).ready(function () {
    $('#nomineeInfo').on('change', '.positionTypes', function () {
        // Get the selected options of all positions
        var allSelected = $(".positionTypes").map(function () {
            return $(this).val();
        }).get();

        // set all enabled
        $(".positionTypes option").removeAttr("disabled");

        // Disable selected options in other positions
        $(".positionTypes option:not(:selected):not([value='0'])").each(function () {
            if ($.inArray($(this).val(), allSelected) != -1) {
                $(this).attr('disabled', true);
            }
        });
    });
});

DEMO

Upvotes: 3

Related Questions