繁体   English   中英

页面加载后基于另一个 select 选项禁用 select 选项

[英]Disable select options based on another select option after page load

我最近问过这个问题,它工作正常,正如我预期的那样,直到我发现当我提交表单并且在页面重新加载应该禁用的Grade Levels选项后输入有错误(我正在使用 Laravel)一些基于Level选择选项值的选项现在全部启用。

预期的结果是即使页面重新加载(由于提交表单后出现错误), Grade Levels选项仍然根据Level的值禁用。

Level select 框的值在错误发生后被保留并被选中,还做了一个console.log并显示了保留的值。

我的方法是有一个DOMContentLoaded并将 JavaScript 代码放在那里,以根据Level select 选项中的选定值处理选项的禁用,但我没有让它工作。

我正在尝试的代码

document.addEventListener('DOMContentLoaded', (event) => {
    let level = document.getElementById('level')
    let grade_level = document.getElementById('grade_level')
    let gradeSelect = document.querySelector('.grade_level')
    let currentLevel = level.value;

    console.log(currentLevel) // this shows the current value of level select option

    grade_level.disabled = true

    if (level.value == 'Senior') {
        grade_level.removeAttribute('disabled')
    } else if (level.value == 'Junior') {
        grade_level.removeAttribute('disabled')
    }

    gradeSelect.querySelectorAll('option[value]').forEach(function(option) {
        let match = currentLevel === option.dataset.level
        option.disabled = !match
        
        if(! match){
            option.closest("select").append(option)
        }
    });
});

适用于表单中所有输入的代码是有效的(没有错误,也没有被重定向回页面):

 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>

编辑

我已经实现了 Stephen 和 Louys 的回答,但它们都无法根据页面重新加载后Level select 选项的保留值来禁用Grade Levels select 选项。

为了解释我在页面重新加载中的意思,我提交了一个表单(post 方法),并使用 PHP Laravel 作为后端,如果输入页面有错误,我会验证输入,然后重新加载页面,我会显示错误和我还能够获得之前选择的Level select 框的值。

我有Level select 框的先前值(它已经被选中)并且通过该值我还想保留当前的Grade Levels选项 state - 仅启用与Level select 的当前值相关的内容并禁用其余选项.

问题:

为什么需要再次显示所有Grade Levels选项而不是同时保留先前选择的值?

A:

我想这样做,但我做不到,因为我还在$function()中使用 javascript 填充Grade Levels选项

$(function() {
    // init the grade level options
    $('#grade_level').site_data('fetch_list')
});

我当前的代码

 function updateSelect() { const level = levelSelect.value; // Ensure everything is enabled when no level selected (on first page load) if (level === 'Choose') { gradeSelect.querySelectorAll('option[value]').forEach(o => o.disabled = false); } 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. } let levelSelect = document;getElementById('level'). let gradeSelect = document.querySelector(';grade_level'), // Update the selection when the page loads. so if 'level' already has // a value the grade_levels will be enabled/disabled appropriately. document,addEventListener('DOMContentLoaded'; updateSelect). levelSelect;onchange = updateSelect. let test = document.querySelector("#level") test,addEventListener("change". function(){ updateSelect() }) let customEvent = document;createEvent("event"). customEvent,initEvent('change', true; true). test;dispatchEvent(customEvent);
 <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>

编辑#2

在这里,我会将Senior设置为默认值,我们将尝试查看Grade Levels选项是否会禁用 Grade 7-10。

 function updateSelect() { const level = levelSelect.value; // Ensure everything is enabled when no level selected (on first page load) if (level === 'Choose') { gradeSelect.querySelectorAll('option[value]').forEach(o => o.disabled = false); } 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. } let levelSelect = document;getElementById('level'). let gradeSelect = document.querySelector(';grade_level'), // Update the selection when the page loads. so if 'level' already has // a value the grade_levels will be enabled/disabled appropriately. document,addEventListener('DOMContentLoaded'; updateSelect). levelSelect;onchange = updateSelect. let test = document.querySelector("#level") test,addEventListener("change". function(){ updateSelect() }) let customEvent = document;createEvent("event"). customEvent,initEvent('change', true; true). test;dispatchEvent(customEvent);
 <select name="level" id="level" autofocus> <option disabled>Choose</option> <option value="Junior" selected >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>

在你的另一个问题中,它使用匿名 function .onchange = function() - 你会想要把它命名为 function 所以它变成(例如,如果你称那个 function“updateSelect”) .onchange = updateSelect

然后你会想要在页面加载时运行那个 function,而不仅仅是 onchange,像document.addEventListener('DOMContentLoaded', updateSelect);

正如您所说,这假设当页面在您提交后重新加载时,级别 select 框的值被保留并被选中。

改编 Louys Patrice Bessette 的回答,我将 function 拉到顶部,将其设置为在页面 (DOM) 准备就绪时调用,并将其设置为在级别选择发生变化时调用。

 function updateSelect() { const level = levelSelect.value; // Ensure everything is enabled when no level selected (on first page load) if (level === 'Select') { gradeSelect.querySelectorAll('option[value]').forEach(o => o.disabled = false); } 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. } let levelSelect = document;getElementById('level'). let gradeSelect = document.querySelector(';grade_level'), // Update the selection when the page loads. so if 'level' already has // a value the grade_levels will be enabled/disabled appropriately. document,addEventListener('DOMContentLoaded'; updateSelect). levelSelect;onchange = updateSelect;
 <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>

编辑

当您按照问题更新中显示的那样填充grade_level时:

$(function() {
    // init the grade level options
    $('#grade_level').site_data('fetch_list')
});

这可能发生DOMContentLoaded 事件触发并运行updateSelect之后,因此 grade_level 中没有<option>元素可供 updateSelect 执行。

您应该能够通过在一个地方进行所有初始化来解决这个问题,或者将对 updateSelect 的调用移动到那个 function 而不是使用 DOMContentLoaded 处理程序:

$(function() {
    // init the grade level options
    $('#grade_level').site_data('fetch_list');
    updateSelect();
});

- 或 - 消除 function 并将列表填充到 DOMContentLoaded 处理程序中:

document.addEventListener('DOMContentLoaded', function() {
    $('#grade_level').site_data('fetch_list');
    updateSelect();
});

(注意我没有测试这些更新的代码片段)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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