I have a TreePanel with checkboxes on each node. The tree only has two levels. When the tree is first rendered it only displays the first (highest) level. In other words, in order to see the children the user would have to expand the visible nodes.
I am finding that a parent node must be expanded once before my script below can cascade the checking of the box down to the children. In other words, if I check the parent node (before having ever expanded it) and then expand the node to see the children, the children are not checked. My TreePanel code is as follows
Code:
var fieldTreeList = new Ext.tree.TreePanel({
title : 'Maint History Field Selection',
id : 'fieldNameID',
height : 200,
width : 300,
autoScroll : true,
animate : true,
enableDD : false,
containerScroll : true,
rootVisible : false,
frame : true,
collapsible : false,
collapsed : false,
header : false,
root : {
nodeType: 'async'
},
loader : new Ext.tree.TreeLoader({
url : HistProcSearch.contextPath + '/maintcatlist.do',
requestMethod : 'post',
preloadChildren : true,
baseAttrs : {
checked : false
},
handleResponse : function(response){
response.responseData = Ext.decode(response.responseText).maintCatList;
this.constructor.prototype.handleResponse.call(this, response);
}
}),
listeners: {
'checkchange': function(node, checked){
//WHEN THE TREEE IS FIRST RENDERED THE HIDDEN CHILDREN DO NOT
//APPEAR TO RENDER UNTIL THEY ARE EXPANDED. THUS CASCADING CHECKS
//DO NOT CASCADE. THE BELOW CHUNCK OF CODE EXPOSES ALL THE CHILDREN
// if( node.isExpandable() && !node.isExpanded() )
// {
// node.expand();
// node.collapse();
// }
//CHANGE LOOK OF TEXT
if( checked )
{
node.getUI().addClass('SelectedItem');
if( node.parentNode.text != "Categories" )
{
node.parentNode.getUI().addClass('SelectedItem');
fieldTreeList.suspendEvents(false);
node.parentNode.getUI().toggleCheck(checked);
fieldTreeList.resumeEvents();
}
}
else
{
node.getUI().removeClass('SelectedItem');
//GET PARENT NODE
var p = node.parentNode;
//CHECK TO SEE IF ANY CHILDREN ARE STILL CHECK
//BEFORE UNCHECKING PARENT
var pChecked = 'N';
if( p.hasChildNodes() )
{
p.eachChild(function(n){
if( n.getUI().isChecked() )
pChecked = 'Y';
})
}
if( pChecked == 'N' )
{
node.parentNode.getUI().removeClass('SelectedItem');
fieldTreeList.suspendEvents(false);
node.parentNode.getUI().toggleCheck(checked);
fieldTreeList.resumeEvents();
}
}
//SET CHILDREN SAME AS PARENT
if( node.hasChildNodes() )
{
node.eachChild(function(n){
n.getUI().toggleCheck(checked);
});
}
}
}
});
My code will check and uncheck the children whether they are currently expanded or not, as long as they have been expanded once first. But before they are expanded the first time after loading the tree, the code above does not find the children as it should. It is as if the children nodes do not exist until they are expanded for the first time. I attempted to use the preloadChildren : true config property, but this did not make a difference.
As you can see I have a commented section of my code that expands and collapses any node that is checked so that the children will be available to check or uncheck. There are three problems with this.
- one node in the tree I am dealing with has over 300 child nodes and to expand and collapse them will take too long.
- this expand and collapse happens every time a parent is checked when the children are collapsed
- It is ugly
If the user knows what the children are without expanding the parent and knows he wants to select all the children, the user should be able to check the parent and expect that all the children are check without needing to expand them.
Does anyone have a better solution?