动态禁用下拉已选项:新增行下拉框排除已选值开发需求
需求与现有代码
现有一个支持行克隆的审批流表单(点击+按钮最多可添加至5行),需实现以下两个功能:
- 第二行的「Approver」下拉框需禁用「Super Admin」选项;
- 每新增一行时,该行的下拉框需排除之前所有行已选中的选项,保证每行选择的审批人不重复。
原HTML代码
<form id="flowform" class="form" role="form" autocomplete="off"> <table id="add-flow-level" class="table table-striped table-borderless" style="width: 100%"> <thead> <tr> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <tr> <td> <div class="col-sm-4"> <label class="required ">Min Amount</label> <input type="text" id="minAmount" name="minAmount" class="form-control min" style="border-radius: 1rem; width: 183px;" maxlength="100" required="required" /> </div> </td> <td> <div class="col-sm-4"> <label class="required ">Max Amount</label> <input type="text" id="maxAmount" name="maxAmount" class="form-control max" style="border-radius: 1rem; width: 183px;" maxlength="100" required="required" /> </div> </td> <td> <div class="col-sm-4"> <label class="required">Approver</label> <select class="form-control" id="approver" name="approver" style="border-radius: 1rem; width: 183px;" required="required" > <option th:value="0">Select User</option> <option th:each="usersList : ${usersList}" th:value="${usersList.id}" th:utext="${usersList.firstName +' '+ usersList.lastName}" /> </select> </div> </td> <td> <a href="#" id="addFlowLevelRow" class="btn btn-primary btn-label-left addFlowLevelRow" title="Add Next" style="margin-top: 18px;"> <i class="fa fa-plus" aria-hidden="true"></i> </a> </td> </tr> </tbody> </table> <br> <div class="row"> <label class="control-label col-sm-5" style="margin-top: 8px;"></label> <div class="col-sm-2"> <input type="submit" class="btn btn-primary btn-label-left" value="Save" id="submitbtnflow" name="submitbtnflow" style="border-radius: 1rem;"> </div> <p id="msg" style="color: green;"></p> </div> </form>
原JS代码
var countOfRows =1; $(".addFlowLevelRow").click(function() { var remv = "<a href='#' id='removeFlowLevelRow' class='btn btn-primary btn-label-left removeFlowLevelRow' title='Remove Row' style='margin-top: 33px;'><i class='fa fa-minus' aria-hidden='true'></i></a>"; var txt = $(this).closest("tr").find('#removeFlowLevelRow').attr('href'); if (txt == undefined && countOfRows < 5) { var newRow = $(this).closest("tr").clone(true).appendTo("#add-flow-level").append(remv); if(countOfRows == 4) { document.getElementsByClassName("addFlowLevelRow")[4].style.display = "none"; console.log("Removal of - button at row = "+countOfRows); } countOfRows++; console.log("Number of row = "+countOfRows); } else if(countOfRows < 5){ var newRow = $(this).closest("tr").clone(true).appendTo("#add-flow-level"); if(countOfRows == 4) { document.getElementsByClassName("addFlowLevelRow")[4].style.display = "none"; console.log("Removal of - button at row = "+countOfRows); } countOfRows++; console.log("Number of row =" +countOfRows); } var input = document.getElementsByClassName('max'); newRow.find('.min').val(input.value); newRow.find('.max').val(""); newRow.find('#approver').val(0); }); $(document).on('click', '#removeFlowLevelRow', function(e) { console.log("view----"); $(this).closest("tr").remove(); countOfRows--; console.log("After - Button count is = "+countOfRows); }); $('#approver').on('change', function() { alert("alerrt called"); var select = document.getElementById('approver'); var value = select.options[select.selectedIndex].value; alert(value); var index = value; if (index > -1) { // ${usersList}.splice(index, 1); } alert("ye ky tha"+select.value); //return ${usersList}; });
解决方案
第一步:修正HTML结构(解决id重复问题)
克隆行后会出现重复id,不符合HTML规范,需将表单元素的id改为类名,并把name改为数组格式,确保表单提交时能获取所有行的数据:
<form id="flowform" class="form" role="form" autocomplete="off"> <table id="add-flow-level" class="table table-striped table-borderless" style="width: 100%"> <thead> <tr> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <tr> <td> <div class="col-sm-4"> <label class="required ">Min Amount</label> <input type="text" name="minAmount[]" class="form-control min" style="border-radius: 1rem; width: 183px;" maxlength="100" required="required" /> </div> </td> <td> <div class="col-sm-4"> <label class="required ">Max Amount</label> <input type="text" name="maxAmount[]" class="form-control max" style="border-radius: 1rem; width: 183px;" maxlength="100" required="required" /> </div> </td> <td> <div class="col-sm-4"> <label class="required">Approver</label> <select class="form-control approver" name="approver[]" style="border-radius: 1rem; width: 183px;" required="required" > <option value="0">Select User</option> <option th:each="usersList : ${usersList}" th:value="${usersList.id}" th:utext="${usersList.firstName +' '+ usersList.lastName}" th:classappend="${usersList.firstName +' '+ usersList.lastName == 'Super Admin' ? 'super-admin' : ''}" /> </select> </div> </td> <td> <a href="#" class="btn btn-primary btn-label-left addFlowLevelRow" title="Add Next" style="margin-top: 18px;"> <i class="fa fa-plus" aria-hidden="true"></i> </a> </td> </tr> </tbody> </table> <br> <div class="row"> <label class="control-label col-sm-5" style="margin-top: 8px;"></label> <div class="col-sm-2"> <input type="submit" class="btn btn-primary btn-label-left" value="Save" id="submitbtnflow" name="submitbtnflow" style="border-radius: 1rem;"> </div> <p id="msg" style="color: green;"></p> </div> </form>
说明:给Super Admin选项添加了super-admin类,方便后续识别禁用;所有动态元素的id都已移除,改为类选择器。
第二步:修改JS代码实现需求
var countOfRows = 1; // 获取所有审批人选项的原始HTML(用于克隆时重新生成下拉框) var originalApproverOptions = $('.approver').html(); // 更新所有下拉框的可选选项(排除已选中的值) function updateApproverOptions() { // 收集所有已选中的非0值 var selectedValues = $('.approver').map(function() { return $(this).val() !== '0' ? $(this).val() : null; }).get().filter(val => val !== null); // 遍历每个下拉框,更新可选选项 $('.approver').each(function(index) { // 重置下拉框选项 $(this).html(originalApproverOptions); // 排除其他行已选中的选项 var currentVal = $(this).val(); selectedValues.forEach(val => { if (val !== currentVal) { $(this).find(`option[value="${val}"]`).remove(); } }); // 第二行禁用Super Admin if (index === 1) { $(this).find('.super-admin').prop('disabled', true); } // 恢复当前选中值 if (currentVal !== '0') { $(this).val(currentVal); } }); } $(".addFlowLevelRow").click(function(e) { e.preventDefault(); if (countOfRows >= 5) return; var $currentRow = $(this).closest("tr"); var $newRow = $currentRow.clone(true); // 清空新行的输入值,重置下拉框 $newRow.find('.min').val($currentRow.find('.max').val()); $newRow.find('.max').val(''); $newRow.find('.approver').val('0'); // 添加删除按钮(如果当前行没有的话) if (!$currentRow.find('.removeFlowLevelRow').length) { var remvBtn = `<a href='#' class='btn btn-primary btn-label-left removeFlowLevelRow' title='Remove Row' style='margin-top: 33px;'><i class='fa fa-minus' aria-hidden='true'></i></a>`; $currentRow.append(remvBtn); } $newRow.appendTo("#add-flow-level tbody"); countOfRows++; // 隐藏第5行的添加按钮 if (countOfRows === 5) { $('.addFlowLevelRow').last().hide(); } // 更新下拉框可选选项 updateApproverOptions(); }); $(document).on('click', '.removeFlowLevelRow', function(e) { e.preventDefault(); $(this).closest("tr").remove(); countOfRows--; // 显示添加按钮 $('.addFlowLevelRow').show(); // 更新下拉框可选选项 updateApproverOptions(); }); // 下拉框值改变时更新可选选项 $(document).on('change', '.approver', function() { updateApproverOptions(); });
功能说明
- 第二行禁用Super Admin:在
updateApproverOptions函数中,判断当前下拉框是第二行(索引为1)时,禁用带有super-admin类的选项; - 选项去重:每次新增行、删除行或修改选中值时,调用
updateApproverOptions函数,收集所有已选中的非0值,然后在每个下拉框中移除其他行已选中的选项,确保每行选择不重复; - 修复原代码问题:解决了克隆行id重复的问题,改用类选择器;优化了添加/删除按钮的逻辑,避免重复添加;新行的Min Amount自动填充上一行的Max Amount值。
内容的提问来源于stack exchange,提问作者Akhilesh Raturi
相关产品推荐
相关产品推荐

