2013-03-05 82 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