2013-03-05 87 views
0

我嵌套了无序列表,列表项与它的标题看起来像这样。复选框不确定状态逻辑

<ul> 
    <li><input type="checkbox" /> Header 1</li> 
    <ul> 
     <li><input type="checkbox" value="1" />Item 1</li> 
    </ul> 
    <li><input type="checkbox" /> Header 2</li> 
    <ul> 
     <li><input type="checkbox" value="1" />Item 1</li> 
     <li><input type="checkbox" value="2" />Item 2</li> 
     <li><input type="checkbox" value="3" />Item 3</li> 
     <li><input type="checkbox" value="4" />Item 4</li> 
    </ul> 
    <li><input type="checkbox" /> Header 3</li> 
    <ul> 
     <li><input type="checkbox" value="5" />Item 5</li> 
     <li><input type="checkbox" value="6" />Item 6</li> 
     <li><input type="checkbox" value="7" />Item 7</li> 
     <li><input type="checkbox" value="8" />Item 8</li> 
     <li><input type="checkbox" value="9" />Item 9</li> 
     <li><input type="checkbox" value="10" />Item 10</li> 
     <li><input type="checkbox" value="11" />Item 11</li> 
     <li><input type="checkbox" value="12" />Item 12</li> 
     <li><input type="checkbox" value="13" />Item 13</li> 
     <li><input type="checkbox" value="14" />Item 14</li> 
     <li><input type="checkbox" value="15" />Item 15</li> 
     <li><input type="checkbox" value="16" />Item 16</li> 
    </ul> 
</ul> 

请注意,项目1存在于标题1的列表和标题2的列表中。

我试图完成一些事情。

  1. 当我点击的标题项,它会自动选择或取消选择所有列表项li内它的ul列表紧随其后。
  2. 当我点击一个嵌套的ul内的列表项li我想检查是否所有其他项目都检查(在这种情况下,在标题列表项上放置一个复选标记),或未选中(在这种情况下,删除标题列表项目中的复选标记),如果它是已选中和未选中的混合,则将标题列表项目设置为不确定状态。
  3. 当我检查一个列表项目,比如列表项目1出现在标题1的列表和标题2的列表中时,我希望它取消选中两个项目,或者检查两个列表中的两个项目,并导致签入要求二在受影响的名单上进行。

我真的很难做到这一点,因为我并不是那么擅长JavaScript,而且我迄今读过的所有代码并不真正接近我所需要的。

任何帮助,将不胜感激。我使用的是jQuery 1.9.1,但是如果你想用它来做这件事,那么JavaScript也不错(因为在谷歌开发工具中设置一个制动点来查看发生了什么时,它更容易遵循)。

+0

完整的例子可以我们添加CSS类到标题里,帮助更容易地选择DOM! – rab 2013-03-05 12:11:15

回答

1

我已经加入topList类外UL和类LI头元素,以简化选择,所以你可能要调整,但我认为这应该做你想要什么。在jsfiddle

//selects all items under a header. This might also select checkboxes from other headers if they share a value. Assumes, "this" points to the header LI 
function selectAll() { 
    var $this = $(this); 
    var isChecked = $this.find(":checkbox").prop("checked"); 
    $this.find("+ul :checkbox").each(function() { 
     selectCheckbox($(this), isChecked); 
    }); 
    $(".header + ul").each(updateHeaderState); 
} 

//selects or deselects a checkbox. Also, selects other checkboxes if they share a value 
function selectCheckbox($checkbox, isChecked) { 
    var value = $checkbox.val(); 
    $checkbox.prop("checked", isChecked); 
    $(".topList :checkbox[value="+value+"]").prop("checked", isChecked); 
} 

//updates the state of the header checkbox. Assumes "this" points to the UL element following a header 
function updateHeaderState() { 
    var $this = $(this); 
    var someChecked = $this.find(":checkbox:checked").length > 0; 
    var someUnchecked = $this.find(":checkbox:not(:checked)").length > 0; 

    var $header = $this.prev().find(":checkbox"); 
    $header.prop("indeterminate", someChecked && someUnchecked); 
    $header.prop("checked", someChecked || !someUnchecked); 
} 

$(".header").click(selectAll); 
$(".header + ul li").click(function() { 
    var $this = $(this); 
    var isChecked = $this.find(":checkbox").prop("checked"); 
    selectCheckbox($this.find(":checkbox"), isChecked);  
    $(".header + ul").each(updateHeaderState); 
}); 
+0

美丽的工作!谢谢,我稍后会将其分开,并看看我是否无法通过此示例代码提高自己的技能。你先生,真棒。 – 2013-03-05 14:53:31

+0

由于几个原因而投了票:1)您的HTML不正确。您将UL嵌套在UL中,而不是UL内部的UL(例如yours == UL> UL,correct == UL> LI> UL)以及2)按值选择/取消选择复选框,而不是仅保证当选中标题时,会检查标题复选框的子项。为了实践,大部分工作都做得很好,但是这个代码不符合HTML或在现实世界中可用。这里有一个链接来阐明UL的嵌套:http://stackoverflow.com/a/5899394/225230 – revive 2014-08-11 18:21:25

+0

+1为您的逻辑 – 2014-09-26 11:50:19