做权限的时候,主要实现如下功能
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的值