【发布时间】:2017-12-14 22:26:23
【问题描述】:
考虑以下 HTML sn-p:这基本上是一组嵌套的复选框,使用无序列表标记来创建一般分组。代码是动态生成的,因此我可以根据需要完全控制标记。
代表以下问题的 jsfiddle 位于:http://jsfiddle.net/bwh4rj3h/
我正在尝试创建执行以下操作的 jQuery:
- 单击全选可切换 sn-p 中所有复选框的状态。
- 单击矩阵更深处的复选框将切换所有“子复选框”。例如单击 Group1 复选框将切换组下结构中所有复选框的状态。
- 如果未选中给定组中的任何复选框,则还必须取消选中组复选框(虽然从技术上讲,代表“部分”填充的三态复选框会很好,但这超出了我的问题范围)。例如假设项目 1-1、1-2 和 1-3 都被选中。然后应检查组 1,在此示例中,还应检查“全选”。但是,如果我取消选择第 1-2 项,现在第 1 组不是“完整的”,因此应该取消选中,“全选”也应该取消选中。
好的,所以我有一些适用于下面标记的 jQuery 代码。它工作正常。但它很丑。而且我讨厌丑陋,并且觉得我的逻辑、选择器和/或 HTML 标记存在缺陷,导致事情变得如此丑陋,并且有更好的方法。
很想得到一些反馈,说明什么是更好的方法。就我个人而言,我不必担心超过 2 级的深度,但通用的 N 级深度功能应该不会太难。事实上,如果不是第三种情况,我正在检查“孩子”的状态以查看是否所有内容都被选中/未选中,它会相对简单。我正在做一个 3 次循环(因为评估顺序)的事实让我很难过。
提前感谢您的帮助。 :)
您会注意到我正在使用 :disabled 检查。在我的最终项目中,我将一些复选框设置为禁用,因此它们对我上面列出的 3 个要求“免疫”。由于标记不包含任何禁用的项目,因此这不会影响结果。
<ul>
<li>
<input type="checkbox" id="chkAll" checked/><label for="chkAll">Select All</label>
</li>
<ul>
<li>
<input type="checkbox" id="chkGroup1" checked/><label for="chkGroup1">Group 1</label>
</li>
<ul>
<li>
<input type="checkbox" id="chkGp1-Item1" checked/><label for="chkGp1-Item1">Item 1</label>
</li>
<li>
<input type="checkbox" id="chkGp1-Item2" checked/><label for="chkGp1-Item2">Item 2</label>
</li>
</ul>
</ul>
</ul>
jQuery:
$("input[type=checkbox]:not(:disabled)").on("change", function () {
$(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled)").prop("checked", $(this).prop("checked"));
// Looping 3 times to cover all sublevels. THERE HAS GOT TO BE A BETTER WAY THAN THIS.
for (var i = 0; i < 3; i++) {
$("input[type=checkbox]:not(:disabled)").each(function() {
var uncheckedkidcount = $(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled):not(:checked)").length;
var kidcount = $(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled)").length;
if (kidcount > 0) {
$(this).prop("checked", uncheckedkidcount == 0);
}
});
}
});
【问题讨论】:
标签: javascript jquery checkbox