一个辅助TreeView实现三态Checkbox的JS代码
这个JS文件是根据网上一位高人的代码修改的,他实现了Checkbox的联动选择。我在他的基础上,加上了了三态Checkbox的功能。他的帖子在这:http://blog.csdn.net/xushichang/archive/2009/05/08/4160742.aspx. 先看看效果:
实现checkbox三态的JS代码:
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
objParentCheckBox.indeterminate = true;
相应的,使Checkbox选中和不选中也需要进行小的修改
// 不选中
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = false;
// 选中
objParentCheckBox.indeterminate = false;
objParentCheckBox.checked = true;
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = false;
// 选中
objParentCheckBox.indeterminate = false;
objParentCheckBox.checked = true;
主要的修改包括了对setParentUnChecked、setChildUnChecked等的实现。全部的代码如下:
JS代码
//TreeView onclick 触发事件
// 示例:tv.onclick = "client_OnTreeNodeChecked(event)";
function client_OnTreeNodeChecked(event) {
var objNode;
if (!public_IsObjectNull(event.srcElement)) {
objNode = event.srcElement; // IE
}
else {
objNode = event.target; //FF
}
if (!public_IsCheckBox(objNode))
return;
var objCheckBox = objNode;
if (objCheckBox.checked == true) {
objCheckBox.indeterminate = false;
setChildChecked(objCheckBox);
setParentChecked(objCheckBox);
}
else {
setChildUnChecked(objCheckBox);
setParentUnChecked(objCheckBox);
}
}
//判断对象是否为空
function public_IsObjectNull(element) {
if (element == null || element == "undefined")
return true;
else
return false;
}
//判断对象是否为 CheckBox
function public_IsCheckBox(element) {
if (public_IsObjectNull(element))
return false;
if (element.tagName != "INPUT" || element.type != "checkbox")
return false;
else
return true;
}
//得到包含所有子节点的 Node(Div 对象)
function public_CheckBox2Node(element) {
var objID = element.getAttribute("ID");
objID = objID.substring(0, objID.indexOf("CheckBox"));
return document.getElementById(objID + "Nodes");
}
//得到父节点的 CheckBox
function public_Node2CheckBox(element) {
var objID = element.getAttribute("ID");
objID = objID.substring(0, objID.indexOf("Nodes"));
return document.getElementById(objID + "CheckBox");
}
//得到本节点所在的 Node(Div 对象)
function public_GetParentNode(element) {
var parent = element.parentNode;
var upperTagName = "DIV";
//如果这个元素还不是想要的 tag 就继续上溯
while (parent && (parent.tagName.toUpperCase() != upperTagName)) {
parent = parent.parentNode ? parent.parentNode : parent.parentElement;
}
return parent;
}
//设置节点的父节点 Checked
// state 取0, 1表示三态、选
function setParentChecked(currCheckBox, state) {
var objParentNode = public_GetParentNode(currCheckBox);
if (public_IsObjectNull(objParentNode))
return;
var objParentCheckBox = public_Node2CheckBox(objParentNode);
if (!public_IsCheckBox(objParentCheckBox))
return;
if (state && state == 0) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
}
else {
if (IsMyChildCheckBoxsChecked(objParentNode)) {
objParentCheckBox.indeterminate = false;
objParentCheckBox.checked = true;
state = 1;
}
else {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
state = 0;
}
}
setParentChecked(objParentCheckBox, state);
}
//当父节点的所有子节点都未被选中时,设置父节点 UnChecked
// state取0, 1分别为三态,不选
function setParentUnChecked(currCheckBox, state) {
var objParentNode = public_GetParentNode(currCheckBox);
if (public_IsObjectNull(objParentNode))
return;
var objParentCheckBox = public_Node2CheckBox(objParentNode);
if (!public_IsCheckBox(objParentCheckBox))
return;
if (state && state == 0) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
}
else {
//判断 currCheckBox 的同级节点是否都为 UnChecked.
if (IsMyChildCheckBoxsUnChecked(objParentNode)) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = false;
state = 1;
}
else {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
state = 0;
}
}
setParentUnChecked(objParentCheckBox, state);
}
//设置节点的子节点 UnChecked
function setChildUnChecked(currObj) {
var currNode;
if (public_IsCheckBox(currObj)) {
currNode = public_CheckBox2Node(currObj);
if (public_IsObjectNull(currNode))
return;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox)) {
childCheckBox.checked = false;
childCheckBox.indeterminate = false;
}
setChildUnChecked(childCheckBox);
}
}
//设置节点的子节点 Checked
function setChildChecked(currObj) {
var currNode;
if (public_IsCheckBox(currObj)) {
currNode = public_CheckBox2Node(currObj);
if (public_IsObjectNull(currNode))
return;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox)) {
childCheckBox.checked = true;
childCheckBox.indeterminate = false;
}
setChildChecked(childCheckBox);
}
}
//判断该节点的子节点是否都为 UnChecked
function IsMyChildCheckBoxsUnChecked(currObj) {
var retVal = true;
var currNode;
if (public_IsCheckBox(currObj) && currObj.checked == true) {
return false;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
if (retVal == false)
break;
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox) && childCheckBox.checked == true) {
retVal = false;
break;
}
else
retVal = IsMyChildCheckBoxsUnChecked(childCheckBox);
}
return retVal;
}
//判断该节点的子节点是否都为 Checked
// 注意:currObj 不是 checkbox
function IsMyChildCheckBoxsChecked(currObj) {
var retVal = true;
var currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox) && childCheckBox.checked == false) {
retVal = false;
break;
}
else {
retVal = IsMyChildCheckBoxsChecked(childCheckBox);
if (!retVal) break;
}
}
return retVal;
}
// 示例:tv.onclick = "client_OnTreeNodeChecked(event)";
function client_OnTreeNodeChecked(event) {
var objNode;
if (!public_IsObjectNull(event.srcElement)) {
objNode = event.srcElement; // IE
}
else {
objNode = event.target; //FF
}
if (!public_IsCheckBox(objNode))
return;
var objCheckBox = objNode;
if (objCheckBox.checked == true) {
objCheckBox.indeterminate = false;
setChildChecked(objCheckBox);
setParentChecked(objCheckBox);
}
else {
setChildUnChecked(objCheckBox);
setParentUnChecked(objCheckBox);
}
}
//判断对象是否为空
function public_IsObjectNull(element) {
if (element == null || element == "undefined")
return true;
else
return false;
}
//判断对象是否为 CheckBox
function public_IsCheckBox(element) {
if (public_IsObjectNull(element))
return false;
if (element.tagName != "INPUT" || element.type != "checkbox")
return false;
else
return true;
}
//得到包含所有子节点的 Node(Div 对象)
function public_CheckBox2Node(element) {
var objID = element.getAttribute("ID");
objID = objID.substring(0, objID.indexOf("CheckBox"));
return document.getElementById(objID + "Nodes");
}
//得到父节点的 CheckBox
function public_Node2CheckBox(element) {
var objID = element.getAttribute("ID");
objID = objID.substring(0, objID.indexOf("Nodes"));
return document.getElementById(objID + "CheckBox");
}
//得到本节点所在的 Node(Div 对象)
function public_GetParentNode(element) {
var parent = element.parentNode;
var upperTagName = "DIV";
//如果这个元素还不是想要的 tag 就继续上溯
while (parent && (parent.tagName.toUpperCase() != upperTagName)) {
parent = parent.parentNode ? parent.parentNode : parent.parentElement;
}
return parent;
}
//设置节点的父节点 Checked
// state 取0, 1表示三态、选
function setParentChecked(currCheckBox, state) {
var objParentNode = public_GetParentNode(currCheckBox);
if (public_IsObjectNull(objParentNode))
return;
var objParentCheckBox = public_Node2CheckBox(objParentNode);
if (!public_IsCheckBox(objParentCheckBox))
return;
if (state && state == 0) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
}
else {
if (IsMyChildCheckBoxsChecked(objParentNode)) {
objParentCheckBox.indeterminate = false;
objParentCheckBox.checked = true;
state = 1;
}
else {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
state = 0;
}
}
setParentChecked(objParentCheckBox, state);
}
//当父节点的所有子节点都未被选中时,设置父节点 UnChecked
// state取0, 1分别为三态,不选
function setParentUnChecked(currCheckBox, state) {
var objParentNode = public_GetParentNode(currCheckBox);
if (public_IsObjectNull(objParentNode))
return;
var objParentCheckBox = public_Node2CheckBox(objParentNode);
if (!public_IsCheckBox(objParentCheckBox))
return;
if (state && state == 0) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
}
else {
//判断 currCheckBox 的同级节点是否都为 UnChecked.
if (IsMyChildCheckBoxsUnChecked(objParentNode)) {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = false;
state = 1;
}
else {
objParentCheckBox.checked = false;
objParentCheckBox.indeterminate = true;
state = 0;
}
}
setParentUnChecked(objParentCheckBox, state);
}
//设置节点的子节点 UnChecked
function setChildUnChecked(currObj) {
var currNode;
if (public_IsCheckBox(currObj)) {
currNode = public_CheckBox2Node(currObj);
if (public_IsObjectNull(currNode))
return;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox)) {
childCheckBox.checked = false;
childCheckBox.indeterminate = false;
}
setChildUnChecked(childCheckBox);
}
}
//设置节点的子节点 Checked
function setChildChecked(currObj) {
var currNode;
if (public_IsCheckBox(currObj)) {
currNode = public_CheckBox2Node(currObj);
if (public_IsObjectNull(currNode))
return;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox)) {
childCheckBox.checked = true;
childCheckBox.indeterminate = false;
}
setChildChecked(childCheckBox);
}
}
//判断该节点的子节点是否都为 UnChecked
function IsMyChildCheckBoxsUnChecked(currObj) {
var retVal = true;
var currNode;
if (public_IsCheckBox(currObj) && currObj.checked == true) {
return false;
}
else
currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
if (retVal == false)
break;
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox) && childCheckBox.checked == true) {
retVal = false;
break;
}
else
retVal = IsMyChildCheckBoxsUnChecked(childCheckBox);
}
return retVal;
}
//判断该节点的子节点是否都为 Checked
// 注意:currObj 不是 checkbox
function IsMyChildCheckBoxsChecked(currObj) {
var retVal = true;
var currNode = currObj;
var currNodeChilds = currNode.childNodes;
var count = currNodeChilds.length;
for (var i = 0; i < count; i++) {
var childCheckBox = currNodeChilds[i];
if (public_IsCheckBox(childCheckBox) && childCheckBox.checked == false) {
retVal = false;
break;
}
else {
retVal = IsMyChildCheckBoxsChecked(childCheckBox);
if (!retVal) break;
}
}
return retVal;
}
测试文件ASPX
ASPX代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestTree.aspx.cs" Inherits="Security_TestTree" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
<style type="text/css">
#Treeview1 a {text-decoration:none;}
#Treeview1 a:hover {text-decoration:none;}
#Treeview1 td:hover {text-decoration:none;}
</style>
<script language="javascript" type="text/javascript" src="../js/tree-select.js">
</script>
</head>
<body bgcolor="white">
<form id="form1" runat="server">
<div>
<asp:TreeView ID="Treeview1" runat="server" ImageSet="XPFileExplorer" AutoGenerateDataBindings="false"
ExpandDepth="0" OnTreeNodePopulate="Treeview1_TreeNodePopulate" ShowCheckBoxes="All" ShowExpandCollapse="true"
onclick="javascript:client_OnTreeNodeChecked(event);">
<SelectedNodeStyle BackColor="#B5B5B5"></SelectedNodeStyle>
<Nodes>
<asp:TreeNode Value="D:" Text="D:" PopulateOnDemand="true" SelectAction="SelectExpand"
NavigateUrl="javascript:void(0);"></asp:TreeNode>
</Nodes>
<NodeStyle VerticalPadding="2" Font-Names="Tahoma" Font-Size="8pt" HorizontalPadding="2"
ForeColor="Black"></NodeStyle>
<HoverNodeStyle Font-Underline="True" ForeColor="#6666AA"></HoverNodeStyle>
</asp:TreeView>
</div>
</form>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
<style type="text/css">
#Treeview1 a {text-decoration:none;}
#Treeview1 a:hover {text-decoration:none;}
#Treeview1 td:hover {text-decoration:none;}
</style>
<script language="javascript" type="text/javascript" src="../js/tree-select.js">
</script>
</head>
<body bgcolor="white">
<form id="form1" runat="server">
<div>
<asp:TreeView ID="Treeview1" runat="server" ImageSet="XPFileExplorer" AutoGenerateDataBindings="false"
ExpandDepth="0" OnTreeNodePopulate="Treeview1_TreeNodePopulate" ShowCheckBoxes="All" ShowExpandCollapse="true"
onclick="javascript:client_OnTreeNodeChecked(event);">
<SelectedNodeStyle BackColor="#B5B5B5"></SelectedNodeStyle>
<Nodes>
<asp:TreeNode Value="D:" Text="D:" PopulateOnDemand="true" SelectAction="SelectExpand"
NavigateUrl="javascript:void(0);"></asp:TreeNode>
</Nodes>
<NodeStyle VerticalPadding="2" Font-Names="Tahoma" Font-Size="8pt" HorizontalPadding="2"
ForeColor="Black"></NodeStyle>
<HoverNodeStyle Font-Underline="True" ForeColor="#6666AA"></HoverNodeStyle>
</asp:TreeView>
</div>
</form>
</body>
</html>
ASPX.CS代码如下
ASPX.CS代码
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class Security_TestTree : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Treeview1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
if (IsCallback)
{
if (e.Node.ChildNodes.Count == 0)
{
LoadChildNode(e.Node);
}
}
}
private void LoadChildNode(TreeNode node)
{
DirectoryInfo directory;
directory = new DirectoryInfo(node.Value);
foreach (DirectoryInfo sub in directory.GetDirectories())
{
TreeNode subNode = new TreeNode(sub.Name);
subNode.Value = sub.FullName;
try
{
if (sub.GetDirectories().Length > 0 || sub.GetFiles().Length > 0)
{
subNode.SelectAction = TreeNodeSelectAction.Expand;
subNode.PopulateOnDemand = true;
subNode.NavigateUrl = "javascript:void(0);";
}
}
catch
{
subNode.ImageUrl =
"WebResource.axd?a=s&r=TreeView_XP_Explorer_ParentNode.gif&t=632242003305625000";
}
node.ChildNodes.Add(subNode);
}
foreach (FileInfo fi in directory.GetFiles())
{
TreeNode subNode = new TreeNode(fi.Name);
subNode.SelectAction = TreeNodeSelectAction.Expand;
subNode.NavigateUrl = "javascript:void(0);";
subNode.Value = fi.FullName;
subNode.PopulateOnDemand = false;
node.ChildNodes.Add(subNode);
}
}
}
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class Security_TestTree : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Treeview1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
if (IsCallback)
{
if (e.Node.ChildNodes.Count == 0)
{
LoadChildNode(e.Node);
}
}
}
private void LoadChildNode(TreeNode node)
{
DirectoryInfo directory;
directory = new DirectoryInfo(node.Value);
foreach (DirectoryInfo sub in directory.GetDirectories())
{
TreeNode subNode = new TreeNode(sub.Name);
subNode.Value = sub.FullName;
try
{
if (sub.GetDirectories().Length > 0 || sub.GetFiles().Length > 0)
{
subNode.SelectAction = TreeNodeSelectAction.Expand;
subNode.PopulateOnDemand = true;
subNode.NavigateUrl = "javascript:void(0);";
}
}
catch
{
subNode.ImageUrl =
"WebResource.axd?a=s&r=TreeView_XP_Explorer_ParentNode.gif&t=632242003305625000";
}
node.ChildNodes.Add(subNode);
}
foreach (FileInfo fi in directory.GetFiles())
{
TreeNode subNode = new TreeNode(fi.Name);
subNode.SelectAction = TreeNodeSelectAction.Expand;
subNode.NavigateUrl = "javascript:void(0);";
subNode.Value = fi.FullName;
subNode.PopulateOnDemand = false;
node.ChildNodes.Add(subNode);
}
}
}