MVC Razor动态生成DropDownList选中项跨框禁用/移除方法
实现方案
第一步:先修正Razor视图的控件生成问题
你当前循环生成下拉框的代码有两个会影响JS交互的问题,先调整:
- 不要给循环生成的元素写固定
id="source",HTML规范要求id全局唯一,会导致JS选择元素异常,改成带索引的动态id即可 - 去掉内联的
onchange="test3()"事件绑定,后续统一用前端脚本给同组下拉框绑定事件,更易维护 - 给源列下拉框加一个专用的样式类,方便JS批量选择元素
调整后的Razor循环代码片段:
<table class="table table-bordered"> <thead> <tr> <th class="text-primary text-center">Source Table</th> <th class="text-primary text-center">Destination Table</th> </tr> </thead> <tbody> @for (i = 0; i < Model.mapTables.Count; i++) { <tr> <td> @Html.DropDownListFor(m => m.mapTables[i].sourceColumn, new SelectList(Model.sourceSelectList, "Text", "Value"), new { @id = $"source_{i}", @class = "form-control source-column-select" }) </td> <td> @Html.DropDownListFor(m => m.mapTables[i].targetColumn, new SelectList(Model.desTinationSelectList, "Text", "Value"), new { @class = "form-control" }) </td> </tr> } </tbody> </table>
第二步:编写前端交互逻辑
推荐用禁用选项的方案实现,相比移除选项不需要额外存储原始选项列表,用户也能直观看到选项是被占用而非不存在,逻辑更稳定。
以下是基于jQuery的实现代码(MVC项目默认集成jQuery,直接放在视图底部的script标签中即可):
$(function () { // 给所有源列下拉框绑定值变更事件 $('.source-column-select').on('change', function () { // 先重置所有下拉框中AssestId选项的状态,恢复可选 $('.source-column-select option').each(function () { if ($(this).val() === 'AssestId' || $(this).text() === 'AssestId') { $(this).prop('disabled', false); } }); // 遍历查找当前是否有下拉框选中了AssestId $('.source-column-select').each(function () { const selectedVal = $(this).val(); const selectedText = $(this).find('option:selected').text(); if (selectedVal === 'AssestId' || selectedText === 'AssestId') { // 除了当前选中AssestId的下拉框,其余下拉框的该选项全部禁用 $('.source-column-select').not(this) .find(`option[value="${selectedVal}"]`) .prop('disabled', true); } }); }); // 页面初始化时主动触发一次事件,处理表单回显时已经选中AssestId的场景 $('.source-column-select').trigger('change'); });
扩展说明
- 如果需要实现所有选项都不允许重复选择,只需要去掉代码中针对
AssestId的判断,遍历收集所有下拉框的已选值,逐个给非选中该值的下拉框禁用对应选项即可,逻辑框架完全通用。 - 如果一定要用移除选项的方案,需要在页面加载时先缓存一份源下拉框的完整option列表,每次值变更时先重置所有下拉框的option为初始列表,再移除其他下拉框中已被选中的选项即可。
内容的提问来源于stack exchange,提问作者Atib
相关产品推荐
相关产品推荐

