When doing permissions, the following functions are mainly implemented:
1. If the node is accessible, its parent node must also be accessible;
2. If the node is accessible, its child nodes can also be accessed;
3. If the node is inaccessible, its child nodes are also inaccessible.
Using a number structure with CheckBox can get a good user experience, but the difficulty of programming is also a bit increased. If it is all done by the server, then it will definitely not work if you click on it. You can only use javascript, which is frustrating when debugging with javascript. Very, a word class, and frustrating recursion. I used to use the following method.
<script language="javascript">
<!--
//Initialize node
initchecknode(document.all("tvItemClientID").value,document.all("checked").value)
//Initialize selected node
function initchecknode(tree,tvvalue)
{
//Get the string of the node that needs to initialize the selection state.
var selectedNodes = tvvalue;
var arrayNodes = new Array();
arrayNodes = selectedNodes.split(",");
var AllRootNode=new Array();
AllRootNode=document.getElementById(tree).getChildren();
//Initialize the selected node
findAndCheckedNodes(AllRootNode,arrayNodes);
}
//Initialize the selected node based on the string of the selected node
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];
////If the node is in nodeDatas, initialize checked = true;
nodeData = cNode.getAttribute("NodeData");
for(var j=0;j<nodeDatas.length;j++)
{
if(nodeDatas[j] == nodeData)
{
cNode.setAttribute("checked","true");
break;
}
}
//If there are child nodes, continue recursion
if(parseInt(cNode.getChildren().length)!=0)
findAndCheckedNodes(cNode.getChildren(),nodeDatas);
}
}
}
//-->
//oncheck event
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]);
}
}
}
//Set child node selection
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);
}
}
}
}
//Set child node selection/cancel;
//At the same time, the status of the parent node needs to be set (if it is deselected, only this node and all its contacts are set, and the parent contacts are not involved)
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"))
}
}
}
//Check whether the sub-contact is selected, if one is selected, return true
//Only check the first level nodes.
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
{
//Select all parent nodes
setParent(parentNode,!Pc)
}
}
else
{
parentNode.setAttribute("checked",Pc);
}
}
//Get all node status
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]);
}
}
}
//Add selected node
function AddChecked(node)
{
document.all.checked.value += node.getAttribute("NodeData") + ",";
}
//-->
</script>This method has a big problem, that is, the CheckBox set by the client cannot be obtained on the server side. Now it can only traverse the tree during Check and put the Checked value in a text. Then submit it to the server, and then the server will parse the characters 1@2 @
Now I am using asp.net2.0 and use the following method
function public_GetParentByTagName(element, tagName)
{
var parent = element.parentNode;
var upperTagName = tagName.toUpperCase();
//If this element is not the desired tag, continue tracing up
while (parent && (parent.tagName.toUpperCase() != upperTagName))
{
parent = parent.parentNode ? parent.parentNode : parent.parentElement;
}
return parent;
}
//Set the node's parent node Cheched - if the node is accessible, its parent node must also be accessible
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);
}
//Set the node's child node uncheched - if the node is inaccessible, its child nodes will also be inaccessible.
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);
}
}
//Set the node's child node cheched - if the node can be accessed, its child nodes can also be accessed
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);
}
}
//trigger event
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);
}
}The biggest advantage of this method is that the server can get the Checked value set by javascript. There is no need to download all the trees without clicking. You can just download them once on the server.
//Traverse child nodes
public void GetChildNode(TreeNode Node)
{
foreach (TreeNode node in Node.ChildNodes)
{
if (node.Checked)
{
StrChecked += node.Value+"@";
}
GetChildNode(node);
}
}
}I can still get its Check value