Hi everyone, Adapting Vikram Bhardwaj's original code for fixing various bugs in the TreeView control, I've written up a JScript library. This code is independant of a given TreeView control, so as long as you setup the event handlers up properly it should
work for multiple TreeView controls on the same page. Please let me know if you find any bugs. Instructions for using this script are found in the opening block comment. Note that the functionality I wanted is slightly different than Mr. Bhardwaj's, as explained
in the comment. If this doesn't format properly, just send me an e-mail and I'll forward you the code. Thanks! John LaRusic
/*
MODULE: MS IE TreeView Control client script
PURPOSE: This code fixes numerous bugs in the Microsoft TreeView
control, including the ability to allow postbacks
A TreeView object setup to use this library will have the
following functionality:
a) When a given checkbox is checked, the parent check
boxes will also be checked. *NOTE* This differs from
the functionality that Mr. Bhardwaj originally
supplied.
b) If a given checkbox is unchecked, then if all the
sibiling checkboxes are also not checked, the parent
checkbox will become unchecked.
There are still the occasional bug in this treeview, and I
think its tied to the behavior file for the treeview. If you
see a bug in this code, please bring my attention to it. My
e-mail is johnlr@gmail.com thanks!
AUTHOR: John LaRusic (with many thanks to Mr. Bhardwaj for the problem
definition and solution)
CREDIT: Vikram Bhardwaj wrote most of this code for a single TreeView
object. I simply adapted it by making it a bit more portable
(multiple TreeView objects can share this library) and fixing
a couple of bugs. I also formatted the code nicely and added
comments should anyone want to adapt this.
Mr. Bhardwaj's original post on this code can be found at:
http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=301443
TO USE: Reference this script file on your page and add the following
event handlers (where "treeview1" is the ID of your tree view
object)
<script event="oncheck" for="treeview1">
TreeView_OnCheck(treeview1);
</script>
<script event="onhover" for="treeview1">
TreeView_OnHover(treeview1, event.treeNodeIndex);
</script>
<script event="onload" for="window">
TreeView_Setup(treeview1);
</script>
You also need to add an onclick event handler to your submit
button to call the TreeView_ReadyForPostback for the tree.
For example:
Button1.Attributes.Add("onclick", _
"TreeView_ReadyForPostback(treeview1)")
*/
/*
FUNCTION: TreeView_OnCheck
PURPOSE: Handles the OnCheck event for a TreeView control.
This will check all the parent nodes above the
"checked" node as well as check all the children
nodes below the "checked" node.
PARAMS: objTreeView - The TreeView control ID
*/
function TreeView_OnCheck(objTreeView){
var objNode = objTreeView.getTreeNode(objTreeView.clickedNodeIndex);
// If this node was initially checked, then we need to handle a bug
// in the TreeView control and do exactly the opposite. Once we do
// this once, then we want to continue as normal
if(TreeView_IsInitChecked(objNode)){
TreeView_SetChecked(objNode, !TreeView_IsChecked(objNode));
TreeView_SetInitChecked(objNode, false);
}
// Traverse the children and parents and refresh the tree
var bChecked = TreeView_IsChecked(objNode);
TreeView_TraverseChildren(objNode.getChildren(), bChecked);
TreeView_TraverseParents(objNode, bChecked);
//TreeView_RefreshTree(objTreeView.getChildren());
}
/*
FUNCTION: TreeView_OnHover
PURPOSE: Handles the OnHover event for a TreeView control
It selects the node the user hovered over. This is to help
the program of an expanded node not being the selected node
PARAMS: objTreeView - The TreeView control ID
strNodeIndex - The index of the node to select
*/
function TreeView_OnHover(objTreeView, strNodeIndex){
objTreeView.selectedNodeIndex = strNodeIndex;
}
/*
FUNCTION: TreeView_Setup
PURPOSE: This sets up the TreeView control by building its
StrVals property.
PARAMS: objTreeView - The TreeView control ID
*/
function TreeView_Setup(objTreeView){
TreeView_SetInitCheckedNodes(objTreeView.getChildren());
}
/*
FUNCTION: TreeView_SetInitCheckedNodes
PURPOSE: Sets which nodes in the tree are initially checked or not
PARAMS: arrChildren - An array of children for a node
RETURNS: The StrVal string for a given group of children
*/
function TreeView_SetInitCheckedNodes(arrChildren){
var objChild;
for(var i = 0; i < arrChildren.length; i++){
objChild = arrChildren[i];
// Set whether the nodes were initially checked or not as well
// as set their initial value... yes, they are the same thing,
// but we might change whether a node has been "initially
// checked" or not later to handle a bug.
var blnIsChecked = TreeView_IsChecked(objChild);
TreeView_SetInitChecked(objChild, blnIsChecked);
TreeView_SetInitCheckValue(objChild, blnIsChecked);
// Call this function recursively on the children
TreeView_SetInitCheckedNodes(objChild.getChildren());
}
}
/*
FUNCTION: TreeView_IsChecked
PURPOSE: Determines if a given tree node is checked or not
PARAMS: objNode - A tree node object
RETURNS: True if the node is checked, false if not
*/
function TreeView_IsChecked(objNode){
// This seems like it should be done in one line, but it helps deal with
// the case that the Checked attribute is equal to null
if(objNode.getAttribute("Checked"))
return true;
else
return false;
}
/*
FUNCTION: TreeView_SetChecked
PURPOSE: Sets if a tree node is checked or not
PARAMS: objNode - A tree node object
*/
function TreeView_SetChecked(objNode, blnChecked){
objNode.setAttribute("Checked", blnChecked);
}
/*
FUNCTION: TreeView_IsInitChecked
PURPOSE: Determines if a given tree node was initially checked
PARAMS: objNode - A tree node object
RETURNS: True if the node was initially checked, false if not
*/
function TreeView_IsInitChecked(objNode){
return objNode.getAttribute("InitChecked");
}
/*
FUNCTION: TreeView_SetInitChecked
PURPOSE: Sets if a tree node is initially checked or not
PARAMS: objNode - A tree node object
blnChecked - True if the node was initially checked,
false if not
*/
function TreeView_SetInitChecked(objNode, blnChecked){
objNode.setAttribute("InitChecked", blnChecked);
}
/*
FUNCTION: TreeView_IsInitChecked
PURPOSE: Determines if a given tree node was initially checked
PARAMS: objNode - A tree node object
RETURNS: True if the node was initially checked, false if not
*/
function TreeView_GetInitCheckValue(objNode){
return objNode.getAttribute("InitCheckValue");
}
/*
FUNCTION: TreeView_SetInitCheckValue
PURPOSE: Sets the initially checked value of a node
PARAMS: objNode - A tree node object
blnChecked - True if the node was originally checked,
false if not
*/
function TreeView_SetInitCheckValue(objNode, blnChecked){
objNode.setAttribute("InitCheckValue", blnChecked);
}
/*
FUNCTION: TreeView_TraverseChildren
PURPOSE: A recursive function that traverses through the tree and
checks or unchecks the nodes
PARAMS: arrChildren - An array of nodes
blnChecked - Determines whether to check the nodes or not
*/
function TreeView_TraverseChildren(arrChildren, blnChecked){
var objChild;
for(var i = 0; i < arrChildren.length; i++){
objChild = arrChildren[i];
// Set whether the node is checked or not
TreeView_SetChecked(objChild, blnChecked);
// Call this function recursively on the children of the node
TreeView_TraverseChildren(objChild.getChildren(), blnChecked);
}
}
/*
FUNCTION: TreeView_TraverseParents
PURPOSE: A recursive function that traverses through a node's
parents and checks them
PARAMS: arrChildren - An array of nodes
blnChecked - Determines whether to check the nodes or not
*/
function TreeView_TraverseParents(objNode, blnChecked){
var objParent = objNode.getParent();
if(objParent != null){
// If we are selecting a checkbox, then we want to check all the
// parent checkboxes as well
if(blnChecked){
TreeView_SetChecked(objParent, true);
}
// Otherwise, we want to check to see if any of the siblings of the
// original node are also checked. If they are all not checked,
// then we want to uncheck the parent.
else{
var blnFlag = true;
var arrSiblings = objParent.getChildren();
for(var i = 0; i < arrSiblings.length ; i++){
if(TreeView_IsChecked(arrSiblings[i]))
blnFlag = false;
}
if(blnFlag)
TreeView_SetChecked(objParent, false);
}
// Call this function recursively on the parent
TreeView_TraverseParents(objParent, blnChecked);
}
}
/*
FUNCTION: TreeView_ReadyForPostback
PURPOSE: Readies a tree for a postback
PARAMS: objTreeView - A TreeView control
*/
function TreeView_ReadyForPostback(objTreeView){
if(objTreeView != null)
TreeView_CheckVals(objTreeView, objTreeView.getChildren());
else
alert("ERROR: TreeView object is null");
}
/*
FUNCTION: TreeView_CheckVals
PURPOSE: Signals that nodes have been checked for the postback
PARAMS: objTreeView - A TreeView control
arrChildren - An array of child nodes
*/
function TreeView_CheckVals(objTreeView, arrChildren){
var objChild;
// Loop through all the nodes
for(var i = 0; i < arrChildren.length; i++){
objChild = arrChildren[i];
// If the current value of the node is different from its initial
// value, then we want to queue the oncheck event
if(TreeView_IsChecked(objChild) != TreeView_GetInitCheckValue(objChild))
objTreeView.queueEvent("oncheck", objChild.getNodeIndex());
// Call this function recursively the child nodes of the current
// node
TreeView_CheckVals(objTreeView, objChild.getChildren());
}
}
/*
FUNCTION: TreeView_RefreshTree
PURPOSE: ??? - This was in the Vikram Bhardwaj original code... not
sure if its necessary or not, but I'm leaving it here...
uncomment the call to it in the TreeView_OnCheck method if
you need it
PARAMS: objTreeView - A TreeView control
*/
/*
function TreeView_RefreshTree(arrChildren){
var objChild;
for(var i = 0; i < arrChildren.length; i++){
objChild = arrChildren[i];
TreeView_SetChecked(objChild, TreeView_IsChecked(objChild));
TreeView_RefreshTree(objChild.getChildren());
}
}
*/
BUG : There is a problem if the same checkbox Is checked/unchecked repeatedly for eg say a checkbox is initially checked and then checked/unchecked and checked and again unchecked, it will still have InitChecked attribute as true
HI, Could you please email me the script for TreeView to leyandrew@yahoo.com ? Also, how do i install it to work with the TreeView component? Thank you, Andrey
JohnLR
Member
5 Points
1 Post
TreeView client side script
Jun 04, 2004 02:15 PM|LINK
/* MODULE: MS IE TreeView Control client script PURPOSE: This code fixes numerous bugs in the Microsoft TreeView control, including the ability to allow postbacks A TreeView object setup to use this library will have the following functionality: a) When a given checkbox is checked, the parent check boxes will also be checked. *NOTE* This differs from the functionality that Mr. Bhardwaj originally supplied. b) If a given checkbox is unchecked, then if all the sibiling checkboxes are also not checked, the parent checkbox will become unchecked. There are still the occasional bug in this treeview, and I think its tied to the behavior file for the treeview. If you see a bug in this code, please bring my attention to it. My e-mail is johnlr@gmail.com thanks! AUTHOR: John LaRusic (with many thanks to Mr. Bhardwaj for the problem definition and solution) CREDIT: Vikram Bhardwaj wrote most of this code for a single TreeView object. I simply adapted it by making it a bit more portable (multiple TreeView objects can share this library) and fixing a couple of bugs. I also formatted the code nicely and added comments should anyone want to adapt this. Mr. Bhardwaj's original post on this code can be found at: http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=301443 TO USE: Reference this script file on your page and add the following event handlers (where "treeview1" is the ID of your tree view object) <script event="oncheck" for="treeview1"> TreeView_OnCheck(treeview1); </script> <script event="onhover" for="treeview1"> TreeView_OnHover(treeview1, event.treeNodeIndex); </script> <script event="onload" for="window"> TreeView_Setup(treeview1); </script> You also need to add an onclick event handler to your submit button to call the TreeView_ReadyForPostback for the tree. For example: Button1.Attributes.Add("onclick", _ "TreeView_ReadyForPostback(treeview1)") */ /* FUNCTION: TreeView_OnCheck PURPOSE: Handles the OnCheck event for a TreeView control. This will check all the parent nodes above the "checked" node as well as check all the children nodes below the "checked" node. PARAMS: objTreeView - The TreeView control ID */ function TreeView_OnCheck(objTreeView){ var objNode = objTreeView.getTreeNode(objTreeView.clickedNodeIndex); // If this node was initially checked, then we need to handle a bug // in the TreeView control and do exactly the opposite. Once we do // this once, then we want to continue as normal if(TreeView_IsInitChecked(objNode)){ TreeView_SetChecked(objNode, !TreeView_IsChecked(objNode)); TreeView_SetInitChecked(objNode, false); } // Traverse the children and parents and refresh the tree var bChecked = TreeView_IsChecked(objNode); TreeView_TraverseChildren(objNode.getChildren(), bChecked); TreeView_TraverseParents(objNode, bChecked); //TreeView_RefreshTree(objTreeView.getChildren()); } /* FUNCTION: TreeView_OnHover PURPOSE: Handles the OnHover event for a TreeView control It selects the node the user hovered over. This is to help the program of an expanded node not being the selected node PARAMS: objTreeView - The TreeView control ID strNodeIndex - The index of the node to select */ function TreeView_OnHover(objTreeView, strNodeIndex){ objTreeView.selectedNodeIndex = strNodeIndex; } /* FUNCTION: TreeView_Setup PURPOSE: This sets up the TreeView control by building its StrVals property. PARAMS: objTreeView - The TreeView control ID */ function TreeView_Setup(objTreeView){ TreeView_SetInitCheckedNodes(objTreeView.getChildren()); } /* FUNCTION: TreeView_SetInitCheckedNodes PURPOSE: Sets which nodes in the tree are initially checked or not PARAMS: arrChildren - An array of children for a node RETURNS: The StrVal string for a given group of children */ function TreeView_SetInitCheckedNodes(arrChildren){ var objChild; for(var i = 0; i < arrChildren.length; i++){ objChild = arrChildren[i]; // Set whether the nodes were initially checked or not as well // as set their initial value... yes, they are the same thing, // but we might change whether a node has been "initially // checked" or not later to handle a bug. var blnIsChecked = TreeView_IsChecked(objChild); TreeView_SetInitChecked(objChild, blnIsChecked); TreeView_SetInitCheckValue(objChild, blnIsChecked); // Call this function recursively on the children TreeView_SetInitCheckedNodes(objChild.getChildren()); } } /* FUNCTION: TreeView_IsChecked PURPOSE: Determines if a given tree node is checked or not PARAMS: objNode - A tree node object RETURNS: True if the node is checked, false if not */ function TreeView_IsChecked(objNode){ // This seems like it should be done in one line, but it helps deal with // the case that the Checked attribute is equal to null if(objNode.getAttribute("Checked")) return true; else return false; } /* FUNCTION: TreeView_SetChecked PURPOSE: Sets if a tree node is checked or not PARAMS: objNode - A tree node object */ function TreeView_SetChecked(objNode, blnChecked){ objNode.setAttribute("Checked", blnChecked); } /* FUNCTION: TreeView_IsInitChecked PURPOSE: Determines if a given tree node was initially checked PARAMS: objNode - A tree node object RETURNS: True if the node was initially checked, false if not */ function TreeView_IsInitChecked(objNode){ return objNode.getAttribute("InitChecked"); } /* FUNCTION: TreeView_SetInitChecked PURPOSE: Sets if a tree node is initially checked or not PARAMS: objNode - A tree node object blnChecked - True if the node was initially checked, false if not */ function TreeView_SetInitChecked(objNode, blnChecked){ objNode.setAttribute("InitChecked", blnChecked); } /* FUNCTION: TreeView_IsInitChecked PURPOSE: Determines if a given tree node was initially checked PARAMS: objNode - A tree node object RETURNS: True if the node was initially checked, false if not */ function TreeView_GetInitCheckValue(objNode){ return objNode.getAttribute("InitCheckValue"); } /* FUNCTION: TreeView_SetInitCheckValue PURPOSE: Sets the initially checked value of a node PARAMS: objNode - A tree node object blnChecked - True if the node was originally checked, false if not */ function TreeView_SetInitCheckValue(objNode, blnChecked){ objNode.setAttribute("InitCheckValue", blnChecked); } /* FUNCTION: TreeView_TraverseChildren PURPOSE: A recursive function that traverses through the tree and checks or unchecks the nodes PARAMS: arrChildren - An array of nodes blnChecked - Determines whether to check the nodes or not */ function TreeView_TraverseChildren(arrChildren, blnChecked){ var objChild; for(var i = 0; i < arrChildren.length; i++){ objChild = arrChildren[i]; // Set whether the node is checked or not TreeView_SetChecked(objChild, blnChecked); // Call this function recursively on the children of the node TreeView_TraverseChildren(objChild.getChildren(), blnChecked); } } /* FUNCTION: TreeView_TraverseParents PURPOSE: A recursive function that traverses through a node's parents and checks them PARAMS: arrChildren - An array of nodes blnChecked - Determines whether to check the nodes or not */ function TreeView_TraverseParents(objNode, blnChecked){ var objParent = objNode.getParent(); if(objParent != null){ // If we are selecting a checkbox, then we want to check all the // parent checkboxes as well if(blnChecked){ TreeView_SetChecked(objParent, true); } // Otherwise, we want to check to see if any of the siblings of the // original node are also checked. If they are all not checked, // then we want to uncheck the parent. else{ var blnFlag = true; var arrSiblings = objParent.getChildren(); for(var i = 0; i < arrSiblings.length ; i++){ if(TreeView_IsChecked(arrSiblings[i])) blnFlag = false; } if(blnFlag) TreeView_SetChecked(objParent, false); } // Call this function recursively on the parent TreeView_TraverseParents(objParent, blnChecked); } } /* FUNCTION: TreeView_ReadyForPostback PURPOSE: Readies a tree for a postback PARAMS: objTreeView - A TreeView control */ function TreeView_ReadyForPostback(objTreeView){ if(objTreeView != null) TreeView_CheckVals(objTreeView, objTreeView.getChildren()); else alert("ERROR: TreeView object is null"); } /* FUNCTION: TreeView_CheckVals PURPOSE: Signals that nodes have been checked for the postback PARAMS: objTreeView - A TreeView control arrChildren - An array of child nodes */ function TreeView_CheckVals(objTreeView, arrChildren){ var objChild; // Loop through all the nodes for(var i = 0; i < arrChildren.length; i++){ objChild = arrChildren[i]; // If the current value of the node is different from its initial // value, then we want to queue the oncheck event if(TreeView_IsChecked(objChild) != TreeView_GetInitCheckValue(objChild)) objTreeView.queueEvent("oncheck", objChild.getNodeIndex()); // Call this function recursively the child nodes of the current // node TreeView_CheckVals(objTreeView, objChild.getChildren()); } } /* FUNCTION: TreeView_RefreshTree PURPOSE: ??? - This was in the Vikram Bhardwaj original code... not sure if its necessary or not, but I'm leaving it here... uncomment the call to it in the TreeView_OnCheck method if you need it PARAMS: objTreeView - A TreeView control */ /* function TreeView_RefreshTree(arrChildren){ var objChild; for(var i = 0; i < arrChildren.length; i++){ objChild = arrChildren[i]; TreeView_SetChecked(objChild, TreeView_IsChecked(objChild)); TreeView_RefreshTree(objChild.getChildren()); } } */sundaram123
Member
55 Points
11 Posts
Re: TreeView client side script
Jun 15, 2004 02:20 AM|LINK
Software Gropus
http://www.sfgroups.com
urbancamel
Member
5 Points
1 Post
Re: TreeView client side script
Jul 06, 2004 02:10 PM|LINK
wailoon
Member
75 Points
15 Posts
Re: TreeView client side script
Jul 21, 2004 08:31 AM|LINK
shiju
Member
357 Points
67 Posts
Re: TreeView client side script
Jul 21, 2004 10:11 AM|LINK
Technical Architect
Blog: http://weblogs.asp.net/shijuvarghese/
Twitter : http://twitter.com/shijucv
WideD
Member
5 Points
1 Post
Re: TreeView client side script
Jul 21, 2004 12:14 PM|LINK
swanandmokas...
Member
20 Points
6 Posts
Re: TreeView client side script
Aug 31, 2004 10:22 PM|LINK
prabtrips
Member
45 Points
9 Posts
Re: TreeView client side script
Sep 10, 2004 10:04 PM|LINK
leyandrew
Member
25 Points
5 Posts
Re: TreeView client side script
Sep 12, 2004 12:20 AM|LINK
Lali
Member
30 Points
6 Posts
Re: TreeView client side script
Sep 13, 2004 03:49 PM|LINK