简体   繁体   中英

enable / disable options based on another select option

I'm working on a select box that enables/disable another select box options based on the selected value on the first select box.

The code below works well:

When I select Junior , the grade-level select options are disabled ( Grade 11 & 12 )

When I select Senior the grade-level selection options are disabled ( Grade 7, 8, 9 & 10 )

Problem

When I change back again to Junior or Senior all the options are being disabled

Expectation

When I change back to either Junior or Senior the options for them should be enabled.

<select name="level" id="level" autofocus>
    <option selected disabled>Choose</option>
    <option value="Junior">Junior</option>
    <option value="Senior">Senior</option>
</select>

<select name="grade_level" class="grade_level">
    <option selected disabled>Choose Grade Level</option>
    <option value="Grade 7">Grade 7</option>
    <option value="Grade 8">Grade 8</option>
    <option value="Grade 9">Grade 9</option>
    <option value="Grade 10">Grade 10</option>
    <option value="Grade 11">Grade 11</option>
    <option value="Grade 12">Grade 12</option>
</select>

JavaScript

document.getElementById('level').onchange = function () {
    var level = document.getElementById('level');

    if (level.value == 'Senior') {

        document.querySelectorAll('.grade_level').forEach(function(select) {
            Array.from(select.options).forEach(function(option) {
                console.log(option.value);
                if (option.value.includes('Grade 7') || option.value.includes('Grade 8')
                    || option.value.includes('Grade 9') || option.value.includes('Grade 10')
                ) {
                    select.removeChild(option);
                    select.appendChild(option);
                    option.setAttribute("disabled", true);
                }
            });
        });
    } else if (level.value == 'Junior') {

        document.querySelectorAll('.grade_level').forEach(function(select) {
            Array.from(select.options).forEach(function(option) {
                console.log(select.options);
                if (option.value.includes('Grade 11') || option.value.includes('Grade 12')) {
                    select.removeChild(option);
                    select.appendChild(option);
                    option.setAttribute("disabled", true);
                }
            });
        });
    }
};

Demo:

https://jsfiddle.net/thrivedigital/h4qo7n1c/2/

Using a data-* attribute and the dataset property... Your code could be a lot more concise.

 let gradeSelect = document.querySelector('.grade_level') document.getElementById('level').onchange = function() { let level = this.value; gradeSelect.querySelectorAll('option[value]').forEach(function(option) { option.disabled =.(level === option.dataset;level) }). // Sets the first one (Choose Grade Level) selected gradeSelect.querySelector('option');selected = true };
 <select name="level" id="level" autofocus> <option selected disabled>Choose</option> <option value="Junior">Junior</option> <option value="Senior">Senior</option> </select> <select name="grade_level" class="grade_level"> <option selected disabled>Choose Grade Level</option> <option value="Grade 7" data-level="Junior">Grade 7</option> <option value="Grade 8" data-level="Junior">Grade 8</option> <option value="Grade 9" data-level="Junior">Grade 9</option> <option value="Grade 10" data-level="Junior">Grade 10</option> <option value="Grade 11" data-level="Senior">Grade 11</option> <option value="Grade 12" data-level="Senior">Grade 12</option> </select>

Option

If you want to have the enabled options on top, you can useappend . It moves an already in DOM element.

 let gradeSelect = document.querySelector('.grade_level') document.getElementById('level').onchange = function() { let level = this.value; gradeSelect.querySelectorAll('option[value]').forEach(function(option) { let match = level === option.dataset.level option.disabled =.match if(.match){ option;closest("select").append(option) } }). // Sets the first one (Choose Grade Level) selected gradeSelect;querySelector('option').selected = true };
 <select name="level" id="level" autofocus> <option selected disabled>Choose</option> <option value="Junior">Junior</option> <option value="Senior">Senior</option> </select> <select name="grade_level" class="grade_level"> <option selected disabled>Choose Grade Level</option> <option value="Grade 7" data-level="Junior">Grade 7</option> <option value="Grade 8" data-level="Junior">Grade 8</option> <option value="Grade 9" data-level="Junior">Grade 9</option> <option value="Grade 10" data-level="Junior">Grade 10</option> <option value="Grade 11" data-level="Senior">Grade 11</option> <option value="Grade 12" data-level="Senior">Grade 12</option> </select>

You're disabling the options, but you don't enable it back to do the opposite so after both Junior and Senior are selected, all the Grades options are disabled.

Edit: To select the first option, you just need to set property selectedIndex = 0

 document.getElementById('level').onchange = function () { var level = document.getElementById('level'); if (level.value == 'Senior') { document.querySelectorAll('.grade_level').forEach(function(select) { select.selectedIndex = 0; Array.from(select.options).forEach(function(option) { console.log(option.value); if (option.value.includes('Grade 7') || option.value.includes('Grade 8') || option.value.includes('Grade 9') || option.value.includes('Grade 10') ) { option.setAttribute("disabled", true); } else{ option.removeAttribute("disabled"); } }); }); } else if (level.value == 'Junior') { document.querySelectorAll('.grade_level').forEach(function(select) { select.selectedIndex = 0; Array.from(select.options).forEach(function(option) { console.log(select.options); if (option.value.includes('Grade 11') || option.value.includes('Grade 12')) { option.setAttribute("disabled", true); } else{ option.removeAttribute("disabled"); } }); }); } };
 <select name="level" id="level" autofocus> <option selected disabled>Choose</option> <option value="Junior">Junior</option> <option value="Senior">Senior</option> </select> <select name="grade_level" class="grade_level"> <option selected disabled>Choose Grade Level</option> <option value="Grade 7">Grade 7</option> <option value="Grade 8">Grade 8</option> <option value="Grade 9">Grade 9</option> <option value="Grade 10">Grade 10</option> <option value="Grade 11">Grade 11</option> <option value="Grade 12">Grade 12</option> </select>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM