Home >Web Front-end >JS Tutorial >javascript-TreeView parent-child linkage effect keeps node status consistent_javascript skills
Most of us have used the TreeView control, and the evaluation of this control is also varied, but I think it is a free and open source control anyway, so I still use it. When I first came into contact with ASP.NET, I remember that I needed to make a permission tree to allocate permissions. At that time, I only knew about this tree. After a day of research, I basically understood its server-side behavior. However, due to the limited js level at the time, I am very afraid of the client code and have basically never seen it.
There was a requirement at that time: if a node is selected, all the child nodes of the node must be selected. If all the child nodes of the node are deselected, the node must also be deselected (node consistency), and vice versa.
Another requirement is: it would be better if a three-state tree can be implemented (this is a bit difficult and will not be discussed in this article). This article will detail the previous requirement 1.
First of all, we have to be grateful that Microsoft’s TreeView control is open source. You can easily obtain both client-side code and server-side code. You can download it from Microsoft’s website. I have also seen some articles on the Internet about this problem. Most of them use a js other than TreeView to implement it. I personally think that from an object-oriented point of view, this function belongs to TreeView, so there is no reason to separate it, so today I will Modify TreeView.htc to implement the above functions. To obtain this file (TreeView.htc), you can download it from Microsoft's website.
To be honest, this function has troubled me for a long time. I have always wanted to solve this problem, but I have never had time to study the code in TreeView.htc. Today I finally made up my mind to solve it.
We know that the event processing function needs to be triggered in the oncheck of TreeView. This function is easy to find and can be found in the client script generated by TreeView. The code snippet is as follows:
oncheck="javascript: if (this. clickedNodeIndex != null) this.queueEvent('oncheck', this.clickedNodeIndex)"
From this we can go to htc (htc mentioned in the future refers to TreeView.htc) and find the doCheckboxClick method. Just look at the name to know What does it do (naming is so important, otherwise it will be really tiring to find a certain function in 3000 lines of code).
This method is a function to be used when the user clicks the CheckBox. The function is as follows:
function doCheckboxClick(el){
var checked = private_getAttribute(el,"checked")
el. checked = !checked; var evt = createEventObject(); evt.treeNodeIndex = getNodeIndex(el); g_nodeClicked = el; _tvevtCheck.fire(evt);
setNodeState(el ,el.checked);//maybe need el only,but I think it's safly
}
} The first, second and last lines were added by me. The first and second lines are for the page response. Modifications made when the checked attribute is invalid in the future are passed. According to the original method, el.checked is undefined after submission, so the nodes cannot be synchronized correctly. If the reader is interested, you can give it a try. The setNodeState function, as you can see from the name, is used to set the node state. It passes the currently selected node as a parameter to the function. As mentioned in the comments, you can actually just pass el in instead of a Boolean value, but I think it may be safer to pass it this way, but it doesn't matter, you can modify it if you feel uncomfortable:.
Let’s take a look at the function body of setNodeState. This function consists of two methods, one is to set the status of all child nodes, and the other is to set the status of the parent node of the node. The code is as follows:
function setNodeState(el,state){
_setChildNode(el,state);
_setParentNode(el,state);
}
In order to be able to set All child nodes of the current node Whether it is consistent with the status of the parent node (this node), we need the function _setChildNode. Similarly, in order to make the parent node of the node consistent with the status of the node, we need the _setParentNode function.Both functions are recursive functions and will traverse all child nodes, all parent nodes and sibling nodes (why we need to traverse sibling nodes will be discussed later). Let's first look at the code for traversing child nodes. The code is as follows:
function _setChildNode(el,state){
var childNodes = el.children;
if(childNodes.length > 0){// if has childrens
for (var i = 0 ;i _setChildNode(childNodes[i],state) ; }
}
}
This function first obtains all sub -nodes of the current node. Here you can use the function getChildren method provided by TreeView directly, and the original method I use to use HTML. If the node has child nodes, all child nodes are traversed, and the state of the child nodes is set to be consistent with the state of the current node. The role of the _saveCheckState function will be introduced later. The private_setAttribute method is an internal method for setting attributes provided by TreeView (js does not have the private keyword, this is just an explanation). This method will set the Checked attribute of each node to the current status of the node.
The following is the code for how to set the parent node state:
_setParentNode(el,state){
var parentNode = el.parentElement;
if(parentNode){
if(!_checkSiblingdNode( el)){
private_setAttribute(parentNode,"Checked",state);
_saveCheckState(parentNode);
_setParentNode(parent Node,state); > This function first obtains its parent node. If the parent node exists, it checks the sibling nodes of the current node. It is mentioned above that the sibling nodes need to be checked. The purpose of checking the sibling nodes here is: the status of the parent node is not controlled by the current node. (This situation only exists when the current node has no sibling nodes). If other brothers are selected, the parent node cannot be canceled, which will lead to inconsistency between the sibling nodes and the parent-child nodes. This function also calls the _saveCheckState function, which will be introduced later.
The following code describes how to check the status of sibling nodes. The code is as follows:
function _checkSiblingdNode(el){
var parentNode = el.parentElement;// you can use getParentTreeNode function in this htc, but I like this usage.
for(var i = 0;i tribute (parentNode.children[i],"Checked")){
🎜> You can use the getParentTreeNode method to get the parent node of a node, but I prefer to use the original method: . This will exclude itself (if(el!=parentNode.children[i])).
With the above code, we can achieve consistent selection of parent-child nodes without refreshing on the client. Now let’s introduce the _saveCheckState function. If there is no such function, after the page is submitted, except for the manually clicked node, other No nodes can save state. Therefore, the function of this function is to save the status of all nodes (mainly automatically selected nodes) to ensure that the status of the tree still exists after the return. The following code describes the _saveCheckState function. The code is as follows: }
This method first checks whether the index of the current node is valid, and if it is valid, saves the state. I need to talk about what the queueEvent method does here. I won’t post the code. The actual meaning of this function is to save the client’s operations in a hidden field called __TreeView1_State__, so that when returning, the server will This hidden field initializes the state of the tree. Among them, TreeView1 is the name of TreeView in my test system.
The final problem is deployment. Because htc has been modified, the original htc file needs to be replaced during deployment.
If you need to modify TreeView.htc (after formatting), you can change my message and leave an email on CSDN. My CSDN account is cuike519.
I hope Microsoft can add this function to the TreeView control as soon as possible, and it is best to achieve a polymorphic tree structure. Please browse the relevant comments on the blog, I will update the article in the comments!