做权限的时候,主要实现如下功能 1、该节点可以访问,则他的父节点也必能访问; 2、该节点可以访问,则他的子节点也都能访问; 3、该节点不可访问,则他的子节点也不能访问。 使用带CheckBox的数型结构能得到很好的用户体验,可是编程的难度也是有点增加,如果全部有服务端来完成,那点下刷下,肯定不行,只能使用javascript,javascript调试的时候郁闷的很,一个字类,还有郁闷的递归,麻烦 我以前是使用以下该方法 <script language="javascript"> <!-- //初始化节点 initchecknode(document.all("tvItemClientID").value,document.all("checked").value) //初始化选中节点 function initchecknode(tree,tvvalue) { //获得需要初始化选择状态的节点的字符串. var selectedNodes = tvvalue; var arrayNodes = new Array(); arrayNodes = selectedNodes.split(","); var AllRootNode=new Array(); AllRootNode=document.getElementById(tree).getChildren(); //初始化选择的节点 findAndCheckedNodes(AllRootNode,arrayNodes); } //根据已选择的节点的字符串初始化选择的节点 function findAndCheckedNodes(NodeArray,nodeDatas) { //alert(NodeArray.length); if(parseInt(NodeArray.length)==0) { return; } else { for(var i=0;i<parseInt(NodeArray.length);i++) { var cNode,nodeData; cNode=NodeArray[i]; ////如果该节点在nodeDatas里则初始化checked = true; nodeData = cNode.getAttribute("NodeData"); for(var j=0;j<nodeDatas.length;j++) { if(nodeDatas[j] == nodeData) { cNode.setAttribute("checked","true"); break; } } //如果有子节点,则继续递归 if(parseInt(cNode.getChildren().length)!=0) findAndCheckedNodes(cNode.getChildren(),nodeDatas); } } } //--> //oncheck事件 function tree_oncheck(tree) { var i; var node=tree.getTreeNode(tree.clickedNodeIndex); var Pchecked=tree.getTreeNode(tree.clickedNodeIndex).getAttribute("checked"); setcheck(node,Pchecked); setParent(node,Pchecked); //window.alert(Pchecked); document.all.checked.value = ""; if (tree.getChildren().length > 0) { for (i=0;i<=tree.getChildren().length-1;i++) { if (tree.getChildren()[i].getAttribute("Checked")) { AddChecked(tree.getChildren()[i]); } FindCheckedFromNode(tree.getChildren()[i]); } } } //设置子节点选中 function setcheck(node,Pchecked) { var i; var ChildNode=new Array(); ChildNode=node.getChildren(); if(parseInt(ChildNode.length)==0) { return; } else { for(i=0;i<ChildNode.length;i++) { var cNode; cNode=ChildNode[i]; cNode.setAttribute("Checked",Pchecked); //cNode.Checked = Pchecked; if(parseInt(cNode.getChildren().length)!=0) { setcheck(cNode,Pchecked); } } } } //设置子节点选中/取消; //同时需要设置父节点的状态(如果是取消选中的话,仅仅设置本节点及其所有字接点,不涉及父接点) function setParent(node,Pc) { var parentNode = node.getParent(); if(parentNode) { var parentNodeFather = parentNode.getParent(); if(parentNodeFather) { setParent(parentNode,Pc); } if(Pc) {parentNode.setAttribute("checked",Pc);} else { checkBrother(parentNode,Pc,node.getAttribute("NodeData")) } } } //检查子接点是否有选择的,如果有一个选择了,那返回true //只查第一级节点. function checkBrother(parentNode,Pc,NodeData) { var childNodes = new Array(); childNodes = parentNode.getChildren(); if(childNodes.length >0) { var bChecked = true; for(var i=0;i<childNodes.length;i++) { if(childNodes[i].getAttribute("checked") == true && childNodes[i].getAttribute("NodeData") != NodeData) { //alert(i+childNodes[i].getAttribute("Text")); bChecked = false; break; } } if(bChecked) { parentNode.setAttribute("checked",Pc); } else { //所有父结点选择 setParent(parentNode,!Pc) } } else { parentNode.setAttribute("checked",Pc); } } //获取所有节点状态 function FindCheckedFromNode(node) { var i = 0; var nodes = new Array(); nodes = node.getChildren(); for (i = 0; i <= nodes.length - 1; i++) { if (nodes[i].getAttribute("Checked")) { AddChecked(nodes[i]); } if (parseInt(nodes[i].getChildren().length) != 0 ) { FindCheckedFromNode(nodes[i]); } } } //添加选中节点 function AddChecked(node) { document.all.checked.value += node.getAttribute("NodeData") + ","; } //--> </script>这种方法有个很大的问题,就是他客户端设置的CheckBox在服务器端是不能获取的,现在只能在Check的时候遍历树,并把Checked的值放在一个文本里,然后提交到服务器,然后服务器来解析1@2@这种字符 现在我使用的是asp.net2.0,使用的是以下的方法 function public_GetParentByTagName(element, tagName) { var parent = element.parentNode; var upperTagName = tagName.toUpperCase(); //如果这个元素还不是想要的tag就继续上溯 while (parent && (parent.tagName.toUpperCase() != upperTagName)) { parent = parent.parentNode ? parent.parentNode : parent.parentElement; } return parent; } //设置节点的父节点Cheched——该节点可访问,则他的父节点也必能访问 function setParentChecked(objNode) { var objParentDiv = public_GetParentByTagName(objNode,"div"); if(objParentDiv==null || objParentDiv == "undefined") { return; } var objID = objParentDiv.getAttribute("ID"); objID = objID.substring(0,objID.indexOf("Nodes")); objID = objID+"CheckBox"; var objParentCheckBox = document.getElementById(objID); if(objParentCheckBox==null || objParentCheckBox == "undefined") { return; } if(objParentCheckBox.tagName!="INPUT" && objParentCheckBox.type == "checkbox") return; objParentCheckBox.checked = true; setParentChecked(objParentCheckBox); } //设置节点的子节点uncheched——该节点不可访问,则他的子节点也不能访问 function setChildUnChecked(divID) { var objchild = divID.children; var count = objchild.length; for(var i=0;i<objchild.length;i++) { var tempObj = objchild[i]; if(tempObj.tagName=="INPUT" && tempObj.type == "checkbox") { tempObj.checked = false; } setChildUnChecked(tempObj); } } //设置节点的子节点cheched——该节点可以访问,则他的子节点也都能访问 function setChildChecked(divID) { var objchild = divID.children; var count = objchild.length; for(var i=0;i<objchild.length;i++) { var tempObj = objchild[i]; if(tempObj.tagName=="INPUT" && tempObj.type == "checkbox") { tempObj.checked = true; } setChildChecked(tempObj); } } //触发事件 function CheckEvent() { var objNode = event.srcElement; if(objNode.tagName!="INPUT" || objNode.type!="checkbox") return; if(objNode.checked==true) { setParentChecked(objNode); var objID = objNode.getAttribute("ID"); var objID = objID.substring(0,objID.indexOf("CheckBox")); var objParentDiv = document.getElementById(objID+"Nodes"); if(objParentDiv==null || objParentDiv == "undefined") { return; } setChildChecked(objParentDiv); } else { var objID = objNode.getAttribute("ID"); var objID = objID.substring(0,objID.indexOf("CheckBox")); var objParentDiv = document.getElementById(objID+"Nodes"); if(objParentDiv==null || objParentDiv == "undefined") { return; } setChildUnChecked(objParentDiv); } }这种方法最大的好处就是服务端能得javascript设置的Checked的值,不用没点下就全部把树遍利下,直接在服务端遍利一次就行了 //遍历子节点 public void GetChildNode(TreeNode Node) { foreach (TreeNode node in Node.ChildNodes) { if (node.Checked) { StrChecked += node.Value+"@"; } GetChildNode(node); } } }我照样能得到它的Check的值 |