ASP.NET 2.0 TreeView 設定 ShowCheckBoxes="All" 後,預設不提供父子節點勾選聯動邏輯。本文提供完整 JavaScript 解決方案,實現:父節點勾選 → 所有子節點勾選;子節點全取消 → 父節點取消;部分子節點勾選 → 父節點半選/勾選。
<asp:TreeView ID="TreeView1" Runat="server" DataSourceID="XmlDataSource1"
onclick="client_OnTreeNodeChecked();" ShowCheckBoxes="All">
<DataBindings>...</DataBindings>
</asp:TreeView>
<script language="javascript" type="text/javascript">
function client_OnTreeNodeChecked() {
var obj = window.event.srcElement;
var treeNodeFound = false;
var checkedState;
if (obj.tagName == "INPUT" && obj.type == "checkbox") {
var treeNode = obj;
checkedState = treeNode.checked;
// 向上尋找包含的 TABLE 元素(TreeView 節點容器)
do { obj = obj.parentElement; } while (obj.tagName != "TABLE");
var parentTreeLevel = obj.rows[0].cells.length;
var parentTreeNode = obj.rows[0].cells[0];
var tables = obj.parentElement.getElementsByTagName("TABLE");
var numTables = tables.length;
if (numTables >= 1) {
for (i = 0; i < numTables; i++) {
if (tables[i] == obj) {
treeNodeFound = true;
i++;
if (i == numTables) return;
}
if (treeNodeFound == true) {
var childTreeLevel = tables[i].rows[0].cells.length;
if (childTreeLevel > parentTreeLevel) {
// 子節點層級較深 → 設定勾選狀態
var cell = tables[i].rows[0].cells[childTreeLevel - 1];
var inputs = cell.getElementsByTagName("INPUT");
inputs[0].checked = checkedState;
} else {
return; // 同層或父層停止
}
}
}
}
}
}
</script>
window.event.srcElement 取得觸發元素cells.length 代表節點深度若專案允許使用 jQuery,可大幅簡化程式碼:
$('#TreeView1 input[type=checkbox]').click(function() {
var $this = $(this);
var checked = $this.prop('checked');
// 子節點:同一層級後續的巢狀 table
$this.closest('table').nextAll('table').find('input[type=checkbox]').prop('checked', checked);
// 父節點邏輯需額外判斷所有同層兄弟是否全勾選
});
此實作解決了 TreeView 最常見的互動缺口,適用於權限樹、分類選單、組織架構等多層級勾選場景。