PDA

View Full Version : Custom Template for Ext.tree.TreePanel (Ext.tree.TreeNodeUI)



roymartin
21 Apr 2009, 3:27 PM
Goal
Apply a custom template to the nodes in my Ext.tree.TreePanel

Overview
Despite the numerous plug-ins out there I haven't been able to figure out how to apply a custom template to the nodes in my Ext.tree.TreePanel. It is a custom form that parses large XML request and builds up the array nodes. I need to customize the formatting of the output to include various extra fields and information.
In the basic case I would like to be able to do this:


<h2 class="title">{text}</h2>


I've address this from two different angles:

1. Beforeappend on the tree. Trying to grab the nodes before their added to the tree and overriding their default formatting.

2. Extending Ext.tree.TreeNodeUI and overriding the buf formatting to be the custom formatting that I need

The first option at least registers, I can loop through all the nodes but I cannot set a custom Ext.Template for it.



navigationTree.on('beforeappend', function(tree, parent, node){

var el = Ext.getCmp('navigation').body;
console.log(node);
})
The Second Option i've tried tons of different ways but I simply cannot get it to register the method and I'm never able to see the render actually kick-in.

Here is the override I've been trying:


// private
Ext.extend(Ext.tree.customNodeUI, Ext.tree.TreeNodeUI, {
renderElements: function(n, a, targetNode, bulkRender){

console.log('test');

// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

var cb = typeof a.checked == 'boolean';

var href = a.href ? a.href : Ext.isGecko ? "" : "#";
var buf = ['<li class="x-tree-node"><div ext:tree-node-id="', n.id, '" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls, '" unselectable="on">', '<span class="x-tree-node-indent">', this.indentMarkup, "</span>", '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />', '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon', (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " " + a.iconCls : ""), '" unselectable="on" />', cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '', '<a hidefocus="on" class="x-tree-node-anchor" href="', href, '" tabIndex="1" ', a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">', n.text, "</span></a></div>", '<ul class="x-tree-node-ct" style="display:none;"></ul>', "</li>"].join('');

var nel;
if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
} else {
this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
}

this.elNode = this.wrap.childNodes[0];
this.ctNode = this.wrap.childNodes[1];
var cs = this.elNode.childNodes;
this.indentNode = cs[0];
this.ecNode = cs[1];
this.iconNode = cs[2];
var index = 3;
if (cb) {
this.checkbox = cs[3];
// fix for IE6
this.checkbox.defaultChecked = this.checkbox.checked;
index++;
}
this.anchor = cs[index];
this.textNode = cs[index].firstChild;
}
});

Finally here is my treepanel:


var navigationLoader = new Ext.tree.TreeLoader({
baseAttrs: {
uiProviders: Ext.tree.customNodeUI
}
});

navigationLoader.createNode = function(attr){

var node;
if (attr.hasChildren) {
node = new Ext.tree.AsyncTreeNode(attr);
if (node.id == 'applications') {
node.loader = ecs.Application.getNavigationLoader();
} else if (node.id == 'credentials') {
node.loader = ecs.Credential.getNavigationLoader();
} else if (node.id == 'users') {
node.loader = ecs.User.getNavigationLoader();
}

} else {
attr.expanded = true;
node = new Ext.tree.TreeNode(attr);
}
var text = node.text;
node.setText(text);
return node;
}

var navigationTree = new Ext.tree.TreePanel({
region: 'west',
id: 'navigation',
collapsible: true,
title: 'Navigation',
width: 214,
autoScroll: true,
rootVisible: false,
cmargins: '5 0 0 0',
padding: '0 0 0 0',
loader: navigationLoader,
// default tree elements for the navigation
root: new Ext.tree.AsyncTreeNode({
text: '',
children: [{
text: 'Instance',
id: 'instance',
leaf: true
}, {
text: 'Applications',
id: 'applications',
leaf: false,
title: 'Applications',
hasChildren: true,
singleClickExpand: true
}, {
text: 'Credentials',
id: 'credentials',
leaf: false,
hasChildren: true,
singleClickExpand: true

}, {
text: 'Resources',
id: 'resources',
leaf: true
}, {
text: 'Users',
id: 'users',
leaf: false,
hasChildren: true,
singleClickExpand: true
}]
})
});

roymartin
21 Apr 2009, 4:01 PM
I accenidently discovered that AsyncTreeNode took a uiProvider as well, dropping that in worked for the first node but it didn't apply to any of the other nodes. I tried adding the same option to the other treenodes without success. Here is what I added to get it to work for the root node only



var navigationTree = new Ext.tree.TreePanel({
region: 'west',
id: 'navigation',
collapsible: true,
title: 'Navigation',
width: 214,
autoScroll: true,
rootVisible: false,
cmargins: '5 0 0 0',
padding: '0 0 0 0',
loader: navigationLoader,
// default tree elements for the navigation
root: new Ext.tree.AsyncTreeNode({
text: '',
uiProvider: Ext.tree.customNodeUI,
children: [{
text: 'Instance',
id: 'instance',
leaf: true
}, {
text: 'Applications',
id: 'applications',
leaf: false,
title: 'Applications',
hasChildren: true,
singleClickExpand: true
}, {
text: 'Credentials',
id: 'credentials',
leaf: false,
hasChildren: true,
singleClickExpand: true

}, {
text: 'Resources',
id: 'resources',
leaf: true
}, {
text: 'Users',
id: 'users',
leaf: false,
hasChildren: true,
singleClickExpand: true
}]
})
});

osheh
24 Jul 2009, 10:42 AM
Hows the current code works for your?
Have you finalize your code?
I need this code for my application...

smokeman
30 Oct 2009, 10:01 AM
I'd love to see completed code....I'm having trouble getting nodes to custom render.

verunder
28 Oct 2013, 10:03 AM
I figured I would rather resurrect this topic instead of opening a new one. Primarily because I'm using the ExtJs 3.4 and I do not need any "node editing" functionality. Just very-customized rendering.

I was able to render a tree node using a custom class extending the Ext.tree.TreeNodeUI, with override of renderElements function. That worked like magic.

Now, I was wondering if it is possible to attach a layout "control" to the node "elNode", "wrap", or any of the sub-elements? Is there a reason I shouldn't be doing that? Anyone could share an example?