带搜索的复选框下拉菜单:实现全选仅选中显示项的需求
问题:搜索后全选仅选中当前显示的复选框
我有一个具备搜索和全选功能的复选框下拉菜单,两者基础功能均正常。但存在一个问题:当进行搜索后,点击全选按钮时,希望仅选中当前显示的复选框,而非全部复选框,目前点击全选仍会选中所有复选框。
修复方案
1. 修正HTML中的重复ID问题(重要)
原循环中所有复选框和关联标签的ID重复,会导致标签关联失效,先修正这部分:
<ul id="getMerchant" class="h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownSearchButton"> @foreach($mids as $mid) <li> <div class="flex items-center p-2 rounded hover:bg-gray-100 "> <input id="merchant-{{$mid->mid_id}}" name="merchant[]" type="checkbox" value="{{$mid->mid_id}}" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 "> <label for="merchant-{{$mid->mid_id}}" class="w-full ml-2 text-sm font-medium text-gray-900 rounded ">{{$mid->mid_name}}</label> </div> </li> @endforeach </ul>
2. 修改全选函数逻辑
原selectAll函数会选中所有复选框(包括全选按钮本身),现在修改为仅选中显示状态的列表项里的复选框:
<script> function filterFunction() { var input, filter, ul, li, i; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); ul = document.getElementById("getMerchant"); li = ul.getElementsByTagName("li"); for (i = 0; i < li.length; i++) { txtValue = li[i].textContent || li[i].innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { li[i].style.display = ""; } else { li[i].style.display = "none"; } } } function selectAll(){ const isChecked = document.getElementById("checkbox-item-14").checked; // 只选择列表内的复选框,排除全选按钮 const merchantCheckboxes = document.querySelectorAll("#getMerchant li input[type=checkbox]"); merchantCheckboxes.forEach(checkbox => { // 仅处理当前显示的列表项中的复选框 const listItem = checkbox.closest("li"); if (listItem.style.display !== "none") { checkbox.checked = isChecked; } }); } </script>
关键修改点
- 通过
closest("li")获取复选框所在的列表项,判断其display状态,仅处理未隐藏的项 - 明确限定选择范围为
#getMerchant li input[type=checkbox],避免误操作全选按钮本身 - 用
forEach遍历替代传统for循环,代码更简洁易读
内容的提问来源于stack exchange,提问作者karen
相关产品推荐
相关产品推荐

