如何使用select picker实现选中选项后在其他下拉框中隐藏该选项
问题描述
我们这里共有三个房间选择下拉框,每个下拉框都有三个完全相同的选项,每个用户每个房间仅可选择一个选项,且已选过的选项不可在其他房间重复选择。

举个例子:假设用户名为John,他在第一个房间的下拉框中选择了选项1,那么第二个和第三个房间的下拉框中,选项1都需要通过jQuery隐藏。
目前我写的代码在未使用selectpicker时可以正常运行,但引入selectpicker后就无法生效,原代码如下:
<!doctype html> <html lang="fa" dir="rtl"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/bootstrap.rtl.min.css"> <link rel="stylesheet" href="css/bootstrap-select.css"> <title>Hello, world!</title> </head> <body> <div class="container mt-5"> <div class="row"> <div class="col-md-4"> <label for="roomOne" class="form-label">Room One</label> <select name="roomOne" id="roomOne" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> <div class="col-md-4"> <label for="roomTwo" class="form-label">Room Two</label> <select name="roomTwo" id="roomTwo" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> <div class="col-md-4"> <label for="roomThree" class="form-label">Room Three</label> <select name="roomThree" id="roomThree" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> </div> </div> <script src="js/bootstrap.bundle.min.js"></script> <script src="js/jquery-3.6.0.min.js"></script> <script src="js/bootstrap-select.js"></script> <script> const selects = document.querySelectorAll('.form-select'); selects.forEach((elem) => { elem.addEventListener('change', (event) => { let values = Array.from(selects).map(select => select.value); for (let select of selects) { select.querySelectorAll('option').forEach((option) => { let value = option.value; if (value && value !== select.value && values.includes(value)) { option.hidden = true; $('.selectpicker').selectpicker('refresh'); } else { option.hidden = false; } }); } }); }); </script> </body> </html>
错误原因
- 选择器不匹配:代码中查询元素用的选择器是
.form-select,但实际<select>标签绑定的类是form-control,导致事件没有绑定到对应元素 - 事件绑定错误:bootstrap-select插件会封装原生select组件,原生change事件可能无法正常触发,需要使用插件提供的
changed.bs.select事件监听值变更 - 依赖引入顺序错误:jQuery是Bootstrap和bootstrap-select的前置依赖,需要放在最前面引入,原代码中bootstrap.bundle.min.js放在jquery之前,会导致插件初始化失败
- refresh调用时机错误:
selectpicker('refresh')放在循环内会重复执行多次,应该在所有option的隐藏状态设置完成后统一调用一次即可
修正后代码
<!doctype html> <html lang="fa" dir="rtl"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/bootstrap.rtl.min.css"> <link rel="stylesheet" href="css/bootstrap-select.css"> <title>Hello, world!</title> </head> <body> <div class="container mt-5"> <div class="row"> <div class="col-md-4"> <label for="roomOne" class="form-label">Room One</label> <select name="roomOne" id="roomOne" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> <div class="col-md-4"> <label for="roomTwo" class="form-label">Room Two</label> <select name="roomTwo" id="roomTwo" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> <div class="col-md-4"> <label for="roomThree" class="form-label">Room Three</label> <select name="roomThree" id="roomThree" class="form-control selectpicker"> <option value="1" data-value="one">One</option> <option value="2" data-value="two">Two</option> <option value="3" data-value="three">Three</option> </select> </div> </div> </div> <!-- 修正依赖引入顺序,jQuery放在最前面 --> <script src="js/jquery-3.6.0.min.js"></script> <script src="js/bootstrap.bundle.min.js"></script> <script src="js/bootstrap-select.js"></script> <script> $(function(){ const $selects = $('.selectpicker'); // 手动初始化selectpicker $selects.selectpicker(); // 绑定bootstrap-select提供的值变更事件 $selects.on('changed.bs.select', function(){ // 收集所有已选的非空值 const selectedValues = $selects.map(function(){ return $(this).val(); }).get().filter(val => val); // 遍历每个下拉框设置option的显示隐藏 $selects.each(function(){ const currentSelectVal = $(this).val(); $(this).find('option').each(function(){ const optVal = $(this).val(); // 已被其他下拉框选中的值隐藏 $(this).prop('hidden', optVal && optVal !== currentSelectVal && selectedValues.includes(optVal)); }); }); // 统一刷新所有selectpicker渲染 $selects.selectpicker('refresh'); }); }) </script> </body> </html>
内容的提问来源于stack exchange,提问作者user15514832
相关产品推荐
相关产品推荐

