<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyTree.aspx.cs" Inherits="test_test_dhtmlTree" %> <!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 runat="server"> <title></title> <script src="js/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <!--树图层开始--> <div id="tvModel" onclick="postBackByObject(event)"> <asp:Label ID="lTree" runat="server" CssClass="treeFont"></asp:Label> </div> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> <!--树图层结束--> <script type="text/javascript"> function ShowChild(vlink) { var vCurrent = $(vlink); //得到鼠标点击的span元素 var vImg = vCurrent.children("img"); //得到span的子元素图像元素 var vImgSrc = vImg.attr("src"); //得到图像的src; var vchild = vCurrent.parent("td").parent("tr").parents("table").next("div"); //得到对应的所有子节点所在的层 if (vImgSrc == "images/treeImage/plus.gif")//切换图像折叠或者展开 { vImg.attr("src", "images/treeImage/add.gif"); } else { vImg.attr("src", "images/treeImage/plus.gif"); } vchild.toggle(); //子层显示或者隐藏 } </script> <script type="text/javascript"> function postBackByObject(e) { //兼容FireFox的写法,FireFox没有window.event.srcElement; var o = e.target || window.event.srcElement; if (o == null) { return; } if (o.tagName == "INPUT" && o.type == "checkbox" && (o.id.indexOf("ckedit_") != -1 || o.id.indexOf("cksearch_") != -1)) //选中了设置权限的CheckBox { return; } if (o.tagName == "INPUT" && o.type == "checkbox") //点击treeview的checkbox是触发 { var d = o.id; //获得当前checkbox的id; var e = d.replace("ck_", "Nodes"); //通过查看脚本信息,获得包含所有子节点div的id var div = window.document.getElementById(e); //获得div对象 if (div != null) //如果不为空则表示,存在自节点 { var check = div.getElementsByTagName("INPUT"); //获得div中所有的已input开始的标记 for (i = 0; i < check.length; i++) { if (check[i].type == "checkbox") //如果是checkbox { check[i].checked = o.checked; //字节点的状态和父节点的状态相同,即达到全选 } } PostParentNode(o); } else //点子节点的时候,使父节点的状态改变,即不为全选 { PostParentNode(o); } } } function PostParentNode(o) { var divid = o.parentElement.parentElement.parentElement.parentElement.parentElement; //子节点所在的div var id = divid.id.replace("Nodes", "ck_"); //获得根节点的id var vCheckBox = window.document.getElementById(id); //父CheckBox,新增递归调用 add bywfz var checkbox = divid.getElementsByTagName("INPUT"); //获取所有子节点数 var s = 0; for (i = 0; i < checkbox.length; i++) { if (checkbox[i].checked) //判断有多少子节点被选中 { s++; } } if (s > 0) //如果全部选中 或者 选择的是另外一个根节点的子节点 , { // 则开始的根节点的状态仍然为选中状态 window.document.getElementById(id).checked = true; if (vCheckBox.tagName == "INPUT" && vCheckBox.type == "checkbox") { PostParentNode(vCheckBox); //递归调用 } } else { //否则为没选中状态 window.document.getElementById(id).checked = false; if (vCheckBox.tagName == "INPUT" && vCheckBox.type == "checkbox") { PostParentNode(vCheckBox); //递归调用 } } } </script> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Text; using System.Data; using System.Web.UI; using System.Web.UI.WebControls; public partial class test_test_dhtmlTree : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { ViewState["dtTree"] = createDT(); ViewState["dtAction"] = createActionDT(); BindTree(); } } #region 绑定顶级树 /// <summary> /// ck_开头表示树上的带CheckBox的节点,后面的参数是该节点的编号 /// </summary> protected void BindTree()//外层树根节点 { StringBuilder sb = new StringBuilder(); DataTable dt = (DataTable)ViewState["dtTree"]; DataRow[] drArr = dt.Select(" parent_id='0' "); foreach (DataRow dr1 in drArr) { string name = dr1["module_name"].ToString(); string id = dr1["module_id"].ToString(); string sParent = @"<table cellpadding='0' cellspacing='0' style='border-0;' > <tr > <td > <span id='sParent' style='cursor:hand' onclick='javascript:ShowChild(this)'> <img src='images/treeImage/plus.gif' alt='折叠' style='border-0;' /></span> </td> <td style='white-space:nowrap;'><input type='checkbox' name='ck_" + id + "' id='ck_" + id + @"' /> <span id='strParent'>" + name + @"</span> </td> </tr> </table>"; //父节点字符串; sb.Append(sParent); string sChild = BindChild(dt,id, 1); sb.Append(sChild); }//循环结束 this.lTree.Text = sb.ToString(); } #endregion #region 加载子节点 /// <summary> /// 加载子节点 /// </summary> /// <param name="parentId">父节点编号</param> /// <param name="level">第几层子树,层数不同,跟页面最左侧的间隔也不同,要添加td</param> /// <returns></returns> protected string BindChild(DataTable dt, string parentId, int level) //产生子树 { StringBuilder sb = new StringBuilder(); sb.Append("<div id='Nodes" + parentId + "' style='display:block;'>"); //层的id和父节点上的id相同,可以实现选中父节点自动选择子节点。。根据id用js实现 DataRow[] drArr = dt.Select(" parent_id='" + parentId + "' "); foreach (DataRow dr1 in drArr) { string name = dr1["module_name"].ToString(); string id = dr1["module_id"].ToString(); string strBreak = ""; string sChild = @" <table cellpadding='0' cellspacing='0' style='border-0;' > <tr>"; sb.Append(sChild); for (int i = 1; i <= level; i++) { strBreak = strBreak + "<td><div style='20px;height:1px'></div></td>";//不同层级间隔不同 } sb.Append(strBreak); if (HasChild(dt,id) == true) //有子节点的有折叠效果,反之没有 { sb.Append(@"<td > <span id='tvModeln0' style='cursor:hand' onclick='javascript:ShowChild(this)'> <img src='images/treeImage/plus.gif' alt='折叠' style='border-0;' /></span> </td>"); } else { sb.Append(@"<td ><img src='images/treeImage/blank.gif' alt='' /></td>"); } if (HasChild(dt, id) == true) { sChild = @"<td style='white-space:nowrap;'> <input type='checkbox' name='ck_" + id + "' id='ck_" + id + @"' /> <span id='tvModelt1'>" + name + @" </span> </td> </tr> </table>"; } else//没有子节点的,添加代表权限选择的checkBox { string LoopAction = string.Empty; DataRow[] drAction = ((DataTable)ViewState["dtAction"]).Select(" module_id='" + id + "' "); for (int k = 0; k < drAction.Length; k++) { string RamID = id + k.ToString().PadLeft(4, '0'); LoopAction += drAction[k]["action_name"]; LoopAction += "<input type='checkbox' name='ckedit_" + RamID + "' id='ckedit_" + RamID + @"' value='" + id + "@" + drAction[k]["action_id"] + "' />"; } sChild = @"<td style='white-space:nowrap;'> <input type='checkbox' name='ck_" + id + "' id='ck_" + id + @"' /> <span id='tvModelt1'>" + name + @" </span> </td> <td><div style='40px;height:1px'></div></td> <td align='right'>" + LoopAction + @" </td> </tr> </table>"; } sb.Append(sChild); if (HasChild(dt,id) == true) { sb.Append(BindChild(dt,id, level + 1)); } } sb.Append("</div>"); return sb.ToString(); } #endregion #region 检查当前项是否有下级 protected bool HasChild(DataTable dt, string parentId) { bool blReturn = false; DataRow[] drArr = dt.Select(" parent_id='" + parentId + "' "); if (drArr.Length > 0) { blReturn = true; } return blReturn; } #endregion #region 按钮事件 protected void Button1_Click(object sender, EventArgs e) { System.Collections.Specialized.NameValueCollection dic = Request.Form; string[] keys = dic.AllKeys; foreach (string key in keys) { if (key.ToUpper().IndexOf("CKEDIT_") != -1)//选中可维护节点 { Response.Write("key:" + key + " " + "value:" + Request.Form[key] + "<br/>"); } } } #endregion #region 创建数据 protected DataTable createDT() { DataTable dt = new DataTable(); dt.Columns.Add("module_id"); dt.Columns.Add("module_name"); dt.Columns.Add("parent_id"); dt.Columns.Add("module_url"); dt.Columns.Add("module_order"); dt.Rows.Add("M01", "广东", "0", "", "1"); dt.Rows.Add("M0101", "深圳", "M01", "", "100"); dt.Rows.Add("M010101", "南山区", "M0101", "", "1000"); dt.Rows.Add("M010102", "罗湖区", "M0101", "", "1001"); dt.Rows.Add("M010103", "福田区", "M0101", "", "1002"); dt.Rows.Add("M010104", "宝安区", "M0101", "", "1003"); dt.Rows.Add("M010105", "龙岗区", "M0101", "", "1004"); dt.Rows.Add("M0102", "广州", "M01", "", "101"); dt.Rows.Add("M010201", "越秀区", "M0102", "", "1105"); dt.Rows.Add("M010202", "海珠区", "M0102", "", "1106"); dt.Rows.Add("M010203", "天河区", "M0102", "", "1107"); dt.Rows.Add("M010204", "白云区", "M0102", "", "1108"); dt.Rows.Add("M010205", "黄埔区", "M0102", "", "1109"); dt.Rows.Add("M010206", "荔湾区", "M0102", "", "1110"); dt.Rows.Add("M010207", "罗岗区", "M0102", "", "1111"); dt.Rows.Add("M010208", "南沙区", "M0102", "", "1112"); return dt; } protected DataTable createActionDT() { DataTable dt = new DataTable(); dt.Columns.Add("action_id"); dt.Columns.Add("module_id"); dt.Columns.Add("action_name"); dt.Columns.Add("action_order"); dt.Rows.Add("a0001", "M010101", "查看", "1"); dt.Rows.Add("a0002", "M010101", "编辑", "2"); dt.Rows.Add("a0003", "M010101", "删除", "3"); dt.Rows.Add("a0004", "M010101", "锁定", "4"); dt.Rows.Add("a0005", "M010203", "查看", "5"); dt.Rows.Add("a0006", "M010203", "编辑", "6"); dt.Rows.Add("a0007", "M010203", "删除", "7"); dt.Rows.Add("a0008", "M010203", "锁定", "8"); return dt; } #endregion }