如何用JavaScript修复Accordion全选Checkbox与子项的联动失效问题?
修复Bootstrap Accordion权限选择的全选联动问题
问题分析
现有代码仅实现了全选Checkbox控制子项的功能,但未监听子Checkbox的手动变更,导致子项取消选中时,头部全选框状态无法自动同步更新。
修改后的完整代码
HTML部分
<div class="card w-100"> <div class="card-body"> <div class="mb-4"> <h5 class="mb-0">Permissions</h5> </div> <div class="accordion accordion-flush" id="accordionFlushExample"> <div class="accordion-item"> <h2 class="accordion-header" id="flush-headingOne"> <button class="accordion-button collapsed gap-3" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseOne" aria-expanded="false" aria-controls="flush-collapseOne"> <input class="form-check-input" type="checkbox" value="" id="selectAllList1" onclick="toggleAll(this, 'projects')" /> Projects </button> </h2> <div id="flush-collapseOne" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample"> <ul class="list-group"> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list1" name="projects" onchange="updateSelectAll('projects', 'selectAllList1')" /> <label class="form-check-label" for="list1"> Add New Project </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list2" name="projects" onchange="updateSelectAll('projects', 'selectAllList1')" /> <label class="form-check-label" for="list2"> View Project </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list3" name="projects" onchange="updateSelectAll('projects', 'selectAllList1')" /> <label class="form-check-label" for="list3"> Edit Project </label> </div> </li> </ul> </div> </div> <div class="accordion-item"> <h2 class="accordion-header" id="flush-headingTwo"> <button class="accordion-button collapsed gap-3" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseTwo" aria-expanded="false" aria-controls="flush-collapseTwo"> <input class="form-check-input" type="checkbox" value="" id="selectAllList2" onclick="toggleAll(this, 'projectCategory')" /> Project Category </button> </h2> <div id="flush-collapseTwo" class="accordion-collapse collapse" aria-labelledby="flush-headingTwo" data-bs-parent="#accordionFlushExample"> <ul class="list-group"> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list1" name="projectCategory" onchange="updateSelectAll('projectCategory', 'selectAllList2')" /> <label class="form-check-label" for="list1"> Add New Project Category </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list2" name="projectCategory" onchange="updateSelectAll('projectCategory', 'selectAllList2')" /> <label class="form-check-label" for="list2"> View Project Category </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list3" name="projectCategory" onchange="updateSelectAll('projectCategory', 'selectAllList2')" /> <label class="form-check-label" for="list3"> Edit Project Category </label> </div> </li> </ul> </div> </div> <div class="accordion-item"> <h2 class="accordion-header" id="flush-headingThree"> <button class="accordion-button collapsed gap-3" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseThree" aria-expanded="false" aria-controls="flush-collapseThree"> <input class="form-check-input" type="checkbox" value="" id="selectAllList3" onclick="toggleAll(this, 'projectType')" /> Project Type </button> </h2> <div id="flush-collapseThree" class="accordion-collapse collapse" aria-labelledby="flush-headingThree" data-bs-parent="#accordionFlushExample"> <ul class="list-group"> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list1" name="projectType" onchange="updateSelectAll('projectType', 'selectAllList3')" /> <label class="form-check-label" for="list1"> Add New Project Type </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list2" name="projectType" onchange="updateSelectAll('projectType', 'selectAllList3')" /> <label class="form-check-label" for="list2"> View Project Type </label> </div> </li> <li class="list-group-item"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="list3" name="projectType" onchange="updateSelectAll('projectType', 'selectAllList3')" /> <label class="form-check-label" for="list3"> Edit Project Type </label> </div> </li> </ul> </div> </div> </div> </div> </div>
JavaScript部分
// 通用全选/取消全选函数 function toggleAll(source, groupName) { const checkboxes = document.getElementsByName(groupName); checkboxes.forEach(checkbox => checkbox.checked = source.checked); } // 更新全选框状态的通用函数 function updateSelectAll(groupName, selectAllId) { const checkboxes = document.getElementsByName(groupName); const selectAllCheckbox = document.getElementById(selectAllId); // 检查当前组所有子项是否都被选中 selectAllCheckbox.checked = Array.from(checkboxes).every(checkbox => checkbox.checked); }
关键修改说明
- 统一全选逻辑:将原来三个重复的分组全选函数合并为通用的
toggleAll函数,通过传入分组名称实现复用,减少冗余代码。 - 添加子项监听:给每个子Checkbox添加
onchange事件,触发updateSelectAll函数,实时检查同组所有子项的选中状态。 - 同步全选框状态:
updateSelectAll函数通过every方法判断当前组所有子项是否都选中,自动同步对应全选框的选中状态。
内容的提问来源于stack exchange,提问作者Deoxzy
相关产品推荐
相关产品推荐

