I need to be able to specify the images used for expand and collapse TreeNode's. I can do this using iconCls, however this only lets me specify pairs of icons. This means I need to dynamically generate a class file with a potentially large number of .x-tree-node-collapsed myclassN and .x-tree-node-expanded myclassN entries.
It would be considerably easier and faster if I could specify separate expanded and collapsed classes or images for each TreeNode. Something like iconClsexpanded: myclassN, iconClscollapsed: myclassN or iconexpanded: myimageN, iconcollapsed: myimageN.
This would also allow me to have a fixed (static) class file.
I've searched the Forum and didn't find any way to specify separate collapsed & expanded images for each node. Maybe I'm missing something.
I had the idea that it wouldn't be solved with css classes but directly with style that would specify (and override classes') bg image.
You would deliver it directly from server - the only problem is that styles have to be set on some elements of tree nodes - this needs to be checked.
That might work. Is there a way to set styles for a tree node?
Ideally I'd like to see this done via. new TreeNode Config Options.
Creating an override that does what you need is pretty easy. The docs and events should help to understand exactly what this does.
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon =
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon.cre ateSequence(function(){
if(this.node.expanded){
Ext.fly(this.iconNode).replaceClass(this.collapsed Cls, this.expandedCls);
}else{
Ext.fly(this.iconNode).replaceClass(this.expandedC ls, this.collapsedCls);
}
});
You can check, but probably we both wanted to achieve the same with our if blocks...;)
Does it work for you, or not? I mean the whole override.
Can you please try this override?
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon =
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon.cre ateSequence(function(){
if(this.rendered) {
if(this.node.expanded){
Ext.fly(this.iconNode).replaceClass(this.collapsed Cls, this.expandedCls);
}else{
Ext.fly(this.iconNode).replaceClass(this.expandedC ls, this.collapsedCls);
}
}
});
This should solve the problem of undefined until the node is rendered.
Hmm, I'm perhaps not getting it fully...
Before the tree is loaded there are no nodes, are they? What is not displayed correctly then?
I didn't say before the tree is loaded! When the tree is first displayed the images used are not the ones set in the overide because the overide cannot be used until the tree is rendered because this.iconNode is undefined.
When the user clicks [+] or [-] the overide is called and the correct image gets displayed because this.iconNode is now defined.
I hope that is clear.
Hmm, I'm perhaps not getting it fully...
Before the tree is loaded there are no nodes, are they? What is not displayed correctly then?
I don't know by heart; look in the docs please. If it is not there you can extend a class to achieve this behavior.
I had already read the documentation for TreeNode before starting this thread and I can't see a way of specifying individual expand/collapse styles. Extending the class sounds promising, but I wouldn't know where to start.
I'd realy like to see this capablity included as part of ExtJS. Can anyone help me further here?
I am using:
Ext.tree.TreeNodeUI.prototype.updateExpandIcon =
Ext.tree.TreeNodeUI.prototype.updateExpandIcon.cre ateSequence(function()
{
if ( this.iconNode ) // undefined when tree is populated
{
....
and can't see that checking 'if(this.rendered)' will make any difference. But I can try it if you want?
Can you please try this override?
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon =
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon.cre ateSequence(function(){
if(this.rendered) {
if(this.node.expanded){
Ext.fly(this.iconNode).replaceClass(this.collapsed Cls, this.expandedCls);
}else{
Ext.fly(this.iconNode).replaceClass(this.expandedC ls, this.collapsedCls);
}
}
});
This should solve the problem of undefined until the node is rendered.
Hi Jozef,
I'm afraid I don't see how this solves my problem. My tree can 1,000's of Folders (non leaf nodes) and each folder can have expand and collapse images which are different to other folders. I need to be able to simply and efficiently specify these expand and collapse images for each folder node.
If I'm not mistaken your example is just setting the single image (class) to use for leaf nodes.
Jack, thanks for that. I've added the code however when the tree is loaded this.iconNode is undefined and I therefore can't replace the classes until it is loaded and the user expands or contracts a node. So it doesn't solve my problem as is.
Furthermore I'd really like to do this when the tree is loaded vs. mucking with the tree for each and every expand/contract.
If I could just specify separate classes for the expanded and collapsed images at load time, I'd be a very happy camper.
Creating an override that does what you need is pretty easy. The docs and events should help to understand exactly what this does.
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon =
Ext.tree.TreeNodeUI.prorotype.updateExpandIcon.cre ateSequence(function(){
if(this.node.expanded){
Ext.fly(this.iconNode).replaceClass(this.collapsed Cls, this.expandedCls);
}else{
Ext.fly(this.iconNode).replaceClass(this.expandedC ls, this.collapsedCls);
}
});
I can use iconCls but this specifies the pair of images (expand/collapse). What I need is to specify these separately.
I have 75 possible images that can be used. This would mean I need 75x75=5,625 classes!! In reality there is probaly < 30 different expand/collapse image pairs, so I can just create those. However it would be far simpler if I could specify the expand and collapse images individually for each node.
I would have thought this would be a reasonably common use of tree folder nodes and am somewhat suprised at what appears to be less than ideal way to handle this.
Oh yes, your problem is different then...
Hmm, try to look as "style" property propages (if at all) to nodes. You could deliver style for each folder (specifying bg image, whatever) from the server.
If style doesn't propagate (is not set) to nodes you may need to extend TreeNode or TreeNodeUI.
I've already solved this before - see attached picture.
The point is that server delivers cls as a part of json:
[{"id":"root/users/5","text":"demo@default","leaf":true,"cls":"p-user","qtip":"Demo User"} ....This class name is added to the node and you only need to provide a style sheet(s). In my example:
.p-user .x-tree-node-icon {
background-image: url("/img/silk/icons/user.png") !important;
}
.p-group .x-tree-node-icon {
background-image: url("/img/silk/icons/group.png") !important;
}
I don't know by heart; look in the docs please. If it is not there you can extend a class to achieve this behavior.
Oh yes, now I get it.
I guess that it would be possible to override these initial images with css I've posted early in this thread, wouldn't be?
I had the idea that it wouldn't be solved with css classes but directly with style that would specify (and override classes') bg image.
You would deliver it directly from server - the only problem is that styles have to be set on some elements of tree nodes - this needs to be checked.
You can check, but probably we both wanted to achieve the same with our if blocks...;)
Does it work for you, or not? I mean the whole override.
Yes the overide works, but only once the tree is loaded and the user then does an expand or collapse, as I explained earlier. So the initial display does not use the images I want.
How to get a non-typeahead combo?
[2.0] On-the-fly add/remove form fields?
|