PDA

View Full Version : [2.2] Tri-state tree/Tree with themed checkbox [NEW v1.2]



Condor
16 Aug 2008, 2:56 AM
Ext 2.2 introduced a themed checkbox component, but unfortunately the new checkbox theme wasn't used for trees and fieldsets.

So I started out making a TreeNodeUI that would use checkbox images instead of checkbox inputs.
After I finished I couldn't resist making a TreeNodeUI descendant that would do what many of you have asked for: support checkboxes with a grayed/partial state and automatic cascading.

Include TreeCheckbox.css and TreeCheckbox.js to get themed checkboxes in your grid.

Include TriStateNodeUI.css and TriStateNodeUI.js and set the uiProvider to TriStateNodeUI to get automatic update of parent/child checked states.
If your tree is very large or if you are using asynchronous node loading (AsynchTreeNode) you should use AsynchTriStateNodeUI instead of TriStateNodeUI (because children that aren't loaded yet can't be checked/unchecked).

Check out example.html to see how to use the new components.

Version 1.1:
- Removed CSS margin.
- Added getChecked method to return correct checked state, even with AsynchTriStateNodeUI.
- Changed TriStateNodeUI to do a real check cascade and moved the original virtual cascading code to AsynchTriStateNodeUI, to be used when a real cascade is to slow (large tree) or impossible (asynchronous node loading).

New version 1.2:
- Fixed bug when in mixing nodes with and without checkboxes.
- Only fire checkchange if checked stated actually changed.

wm003
16 Aug 2008, 2:26 PM
B)Great Stuff! Thanks for sharing and hopefully this will be included in ext 2.3:D

Condor
18 Aug 2008, 10:15 PM
After working with my new tree a few days I noticed a few problems:

1. The margin:0 1px should be removed from the CSS (it causes cursor flickering).

2. In the example:
- Click 'Column Tree Example' (now 'Abstract rendering in TreeNodeUI', 'Create TreePanel to render and lock headers' and 'Test and make sure it works' look unchecked (but aren't).
- Click 'Test and make sure it works'. Now 'Test and make sure it works' is unchecked and 'Abstract rendering in TreeNodeUI' and 'Create TreePanel to render and lock headers' show their checked state again.

I would like your input in this one: Is this really a problem? Because fixing it would require to actually update the checked state of children which could be slow and doesn't even work correctly in an AsyncTreeNode.

wm003
21 Aug 2008, 11:17 AM
2. In the example:
...
I would like your input in this one: Is this really a problem? Because fixing it would require to actually update the checked state of children which could be slow and doesn't even work correctly in an AsyncTreeNode.

I would keep it this way and rather let the developer react on check/uncheck-events to handle the "partly-checked" checkbox on the parent node (at least this is needed when using async treenodes..i always have to do this in my trees to update the parent node text (becaus it displays the amount of checked childs, so it could also handle the change of the checkbox)

fermo111
22 Aug 2008, 2:10 AM
Very nice!!!

Just one minor problem. I had to delete the line (file test.html)


preloadChildren:true,

because that would give me the following error


R is undefined

and the tree would not load. This is in FF 3 on Linux.

Thanks

Luca

Condor
22 Aug 2008, 3:29 AM
I had to delete the line (file test.html)

preloadChildren:true,
because that would give me the following error

R is undefined
and the tree would not load. This is in FF 3 on Linux.

That is strange...
I have no problems with the file (tested IE 6, IE 7, FF 3.0.0.1, Opera 9.51 and Safari 3.1.2 on Windows XP SP3).

fermo111
22 Aug 2008, 6:07 AM
Sorry, my fault. I wasn't using Ext v2.2.

rtconner
22 Aug 2008, 8:20 AM
2. In the example:
- Click 'Column Tree Example' (now 'Abstract rendering in TreeNodeUI', 'Create TreePanel to render and lock headers' and 'Test and make sure it works' look unchecked (but aren't).
- Click 'Test and make sure it works'. Now 'Test and make sure it works' is unchecked and 'Abstract rendering in TreeNodeUI' and 'Create TreePanel to render and lock headers' show their checked state again.

It's kind of cool the way it is. Like a "remember the checkboxes I had checked" kind of feature. I mean that requires that the developer is a bit smarter on the server side when saving, but outside of the extra effort there, it's fine.

Btw, I don't know if you meant to or not, but double-clicking the checkbox still expands and collapses the tree. To me that is a bit of an unexpected behavior.

rtconner
22 Aug 2008, 8:27 AM
Also do you know, why this type of usage does not work?


new Ext.tree.TreePanel({
rootVisible : false,
root : new Ext.tree.TreeNode({text:'Types', id:'root',
children: data,
uiProvider:Ext.tree.TriStateNodeUI
}),
loader: new Ext.tree.TreeLoader({preloadChildren:true})
})

When I run that, the root is visible, and the children do not get loaded ever.

(sorry for the complaints. this tree is just want I was looking for and really is very nice)

fermo111
22 Aug 2008, 10:13 AM
How many branch levels does it support? I have tried adding a third level but the checkboxes are not updated correctly. This is the data I have tried:



var data = [{
text: 'New Top Node',
checked: null,
expanded: true,
children: [{
text:'ColumnTree Example',
checked:null,
expanded:true,
children:[{
text:'Abstract rendering in TreeNodeUI',
checked:true,
...
...
...
},{
text:'Test and make sure it works',
checked:false,
disabled:true,
leaf:true
}]
}]
}];

rtconner
24 Aug 2008, 8:37 PM
Also, I am completely unable to get it to work with AsyncTreeNode. Do you think I need to try harder, or is that not build into this?

Condor
24 Aug 2008, 10:30 PM
@rtconner: Your example doesn't set the uiProvider for all child nodes. Either set the uiProvider in the baseAttrs of the tree loader (as I did) or specify the uiProvider in every child node (see the ColumnTree example). This also applies to AsyncTreeNode!

@fermo111: It supports an 'unlimited' number of branches. Your example must be flawed somewhere, because I am able to add a number of extra levels without any problem.

ps. TriStateNodeUI does require that you fill the checked config option of the nodes correctly on startup!

fermo111
25 Aug 2008, 12:31 AM
After working with my new tree a few days I noticed a few problems:

1. The margin:0 1px should be removed from the CSS (it causes cursor flickering).

2. In the example:
- Click 'Column Tree Example' (now 'Abstract rendering in TreeNodeUI', 'Create TreePanel to render and lock headers' and 'Test and make sure it works' look unchecked (but aren't).
- Click 'Test and make sure it works'. Now 'Test and make sure it works' is unchecked and 'Abstract rendering in TreeNodeUI' and 'Create TreePanel to render and lock headers' show their checked state again.

I would like your input in this one: Is this really a problem? Because fixing it would require to actually update the checked state of children which could be slow and doesn't even work correctly in an AsyncTreeNode.

This was really the reason why I thought it didn't work when adding an additional level.
Since you ask, I would say the TreeNodeUI should implement the expected behaviour as the user perceives it, that is, when you uncheck a parent node, all the children are really unchecked as well. I understand there is a problem with the AsyncTreeNode, but maybe the AsyncTreeNode is not the right class to use for a control of this kind, or, keeping the async nature of the tree, you could apply the user choices on the parent node to the children nodes that are loaded later.

Thanks

Luca

nicola_java
28 Aug 2008, 11:36 PM
Nice job. :D Thanks for sharing.

skaue
11 Sep 2008, 8:32 AM
I can't get the checkboxes to show in my tree. I have one root with two async children. Here is my setup:



/******
TREE
****/
var tree = new xt.TreePanel({
title: 'Mapper',
collapsible: false,
animCollapse: false,
border: true,
rootVisible: false,
id: "tree_referencearchive",
autoScroll: true,
animate: false,
enableDD: true,
containerScroll: true,
width: 300,
minSize: 175,
maxSize: 400,
useArrows: true,
split: true,
region: 'west',
collapsible: true,
collapsed: false,
useSplitTips: true,
listeners:
{
click: function(node)
{
var store = files.getStore();
store.baseParams.id = node.attributes.id;
store.load();
}
},
baseAttrs: {
uiProvider: Ext.tree.TriStateNodeUI,
checked: false
}
});
var root = new xt.TreeNode({
text: 'Referansedokumenter',
allowDrag: false,
id: 'tree_root',
draggable: false,
preloadChildren: true,
baseAttrs: {
uiProvider: Ext.tree.TriStateNodeUI,
checked: false
}
});

root.appendChild(new xt.AsyncTreeNode(
{
id: 'tags',
text: 'Kategorier',
icon: '/content/images/icons/tag_blue.png',
allowDrag: false,
loader: new xt.TreeLoader({
dataUrl: '/ReferenceArchive/GetTagsTree/',
preloadChildren: true,
baseAttrs: {
uiProvider: Ext.tree.TriStateNodeUI,
checked: false
}
})
}));
root.appendChild(new xt.AsyncTreeNode(
{
id: 'fmentity',
text: 'Fasiliteter',
icon: '/Content/images/icons/chart_organisation.png',
allowDrag: false,
loader: new xt.TreeLoader({
dataUrl: '/FacilitCore/GetTreeJson/',
preloadChildren: true,
baseAttrs: {
uiProvider: Ext.tree.TriStateNodeUI,
checked: false
}
})
}));
tree.setRootNode(root);


Why can't I get this treestate to work. There are no errors, simply no checkboxes.

Condor
11 Sep 2008, 10:09 AM
You are putting the checked config option in baseAttrs of the loader, but it should be in the config of the node itself.
Putting it in baseAttrs doesn't help, because that will copy the checked config option to the node instead of the node attributes.

skaue
11 Sep 2008, 10:22 AM
baseParams? are they the same as baseAttrs? I feel confused (:|

BrainDrain
8 Oct 2008, 1:54 AM
Could some one make text nodes line wrapping for tree?
It will be very useful for long node text labels!

skaue
8 Oct 2008, 1:57 AM
Could some one make text nodes line wrapping for tree?
It will be very useful for long node text labels!

I simply use qtip so if strings are long, the user can always hover over it and see the full text. Similar to how it works in filebrowsers.

Condor
8 Oct 2008, 2:55 AM
Could some one make text nodes line wrapping for tree?
It will be very useful for long node text labels!

You could use:

.x-tree-node a span {white-space: normal;}
(but I don't think you'll like the result)

BrainDrain
8 Oct 2008, 4:45 AM
You could use:

.x-tree-node a span {white-space: normal;}(but I don't think you'll like the result)
Yes, I've already tried - no good
OK, I will try by myself
something like that


.x-tree-node a span
{
white-space: normal;
}
.x-tree-node td
{
vertical-align:top;
}

renderElements: function(n, a, targetNode, bulkRender) {
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var cb = a.checked !== undefined;
var href = a.href ? a.href : Ext.isGecko ? "" : "#";
var iconCls = a.iconCls || 'x-tree-node-icon';
var buf = ['<li class="x-tree-node"><table table border="0" cellpadding="0" cellspacing="0"><tbody><tr ext:tree-node-id="', n.id, '" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls, '" unselectable="off">',
'<td><span class="x-tree-node-indent">', this.indentMarkup, "</span></td>",
'<td><img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" /></td>',
'<td><img src="', a.icon || this.emptyIcon, '" class="' + iconCls, (a.icon ? " x-tree-node-inline-icon" : ""), (a.iconCls ? " " + a.iconCls : ""), '" unselectable="on" /></td>',
cb ? ('<td style="padding-top:4px;"><img src="' + this.emptyIcon + '" class="x-tree-checkbox' + (a.checked === true ? ' x-tree-node-checked' : (a.checked !== false ? ' x-tree-node-grayed' : '')) + '" /></td>') : '',
'<td><a hidefocus="on" class="x-tree-node-anchor" href="', href, '" tabIndex="1" ',
a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">', n.text, "</span></a></td></tr></tbody></table>",
'<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.firstChild.firstChild.firstChild;
this.ctNode = this.wrap.childNodes[1];

var cs = this.elNode.childNodes;
this.indentNode = cs[0].firstChild;
this.ecNode = cs[1].firstChild;
this.iconNode = cs[2].firstChild;
var index = 3;
if (cb) {
this.checkbox = cs[3].firstChild;
index++;
}
this.anchor = cs[index].firstChild;
this.textNode = cs[index].firstChild.firstChild;
}
but I need correct lines displaying

BrainDrain
9 Oct 2008, 11:15 PM
fixed here (http://extjs.com/forum/showthread.php?t=47230&page=2)

Rodolfo
24 Oct 2008, 8:59 AM
getChecked(); not work if you check or uncheck only a parent (folder) node ?

Condor
24 Oct 2008, 11:35 PM
[QUOTE=Rodolfo;243020]getChecked(); not work if you check or uncheck only a parent (folder) node ?

Rodolfo
25 Oct 2008, 10:01 AM
Thanks, works OK..

very useful, i hope this tris state tree will be include in the next extJS release,
(anyway i'm already using in my app ;) )

agalue
17 Nov 2008, 11:39 AM
[quote=Rodolfo;243020]getChecked(); not work if you check or uncheck only a parent (folder) node ?

Condor
17 Nov 2008, 12:15 PM
Hello,

First of all... great plugin... thanks for that....

But, I'm confused. Can any body tell me where can I find the correct implementation of Ext.tree.TriStateNodeUI that don't have issues when you check or uncheck parent folders ?

I had tried with the original post (and suggested patch) but I still have problem with parent folders that affects treePanel.getChecked()


The problem:
Check a child node (parent node appears grayed... ok)
Uncheck parent node (this uncheck all children... ok)
Check other child node different of node checked on step 1 (The result is 2 children are checked .... wrong)

That was the whole point I was trying to make in this post (http://www.extjs.com/forum/showthread.php?p=211300#post211300).
Checking or unchecking a parent node does not actually check on uncheck all child nodes (I could do this, but it could be slow and it wouldn't work for AsychTreeNodes).
I added the getChecked methods, so you can at least reliably find which nodes are visually checked.

agalue
18 Nov 2008, 5:06 AM
Hello Condor,


That was the whole point I was trying to make in this post (http://www.extjs.com/forum/showthread.php?p=211300#post211300).
Checking or unchecking a parent node does not actually check on uncheck all child nodes (I could do this, but it could be slow and it wouldn't work for AsychTreeNodes).
I added the getChecked methods, so you can at least reliably find which nodes are visually checked.

I'm not interersted in using AcyncTreeNodes with this feature, but I'm interested to see even if it's slow the code to correct the problem.

It's confused when you uncheck a parent node that was full checked, and then check only one child and all others childs appears checked!. But, the only node that I spect to be checked appers unchecked!

Can you share the "slow" code please ?

And thanks for your help.

Condor
18 Nov 2008, 5:55 AM
It isn't even all that difficult:

Ext.override(Ext.tree.TriStateNodeUI, {
onCheckChange :function(){
Ext.tree.TriStateNodeUI.superclass.onCheckChange.apply(this, arguments);
var p;
if((p = this.node.parentNode) && p.getUI().updateParent && !p.getUI().isUpdating) {
p.getUI().updateParent();
}
},
updateChild:function(checked){
if(typeof checked == 'boolean'){
this.isUpdating = true;
this.node.eachChild(function(n){
n.getUI().toggleCheck(checked);
}, this);
delete this.isUpdating;
}
}
});

agalue
26 Nov 2008, 10:45 AM
Condor,

I tried your code today and it works perfect. Thank you very much for your help.

Condor
27 Nov 2008, 12:52 AM
I created a new version 1.1 that contains all the previous fixes and updates:

- Removed CSS margin
- Added getChecked method to return correct checked state, even with AsynchTriStateNodeUI.
- Changed TriStateNodeUI to do a real check cascade and moved the original virtual cascading code to AsynchTriStateNodeUI, to be used when a real cascade is to slow (large tree) or impossible (asynchronous node loading).

Dr. Flink
1 Dec 2008, 1:05 AM
I'm having some problems loading tree from server, but when I'm using the example data object, everything is working as it is supposed.


Ewa.Statistics = function() {
// Test data from example.html
var data = [{
text:'ColumnTree Example',
checked:null,
expanded:true,
children:[{
...
...
}]
}];

var heatDs = new Ext.tree.TreeLoader({
url: '/member/statistics/heatTree',
preloadChildren:true,
baseAttrs:{
uiProvider: Ext.tree.TriStateNodeUI
},
listeners: {
beforeload: function(store, node, callback) {
this.baseParams.depth = node.getDepth();
}
}
});

var heatRoot = new Ext.tree.TreeNode({
text: 'Fastigheter',
id: '0'
//children: data
});

var heatPanel = new Ext.Panel({
title: 'Statistik',
iconCls: 'iconStatistics',
layout:'border',
items: [
{
title: 'Fastigheter',
region:'west',
border: false,
width: 300,
layout: 'fit',
items: {
xtype: 'treepanel',
useArrows:true,
border: false,
rootVisible: false,
autoScroll: true,
root: heatRoot
}
},
{
...
}
]
});

return {
activate: function() {
heatDs.load(heatRoot);
}
}
}();If I uncomment the "children: data" -line the example data object is loaded instead and the check/uncheck is acting as it should. But, when commented and the server data is loaded, the check/uncheck is messed up. Hope someone understands my problem and knows what I'm missing.

// Rickard

Update:
Am I supposed to use the children-attribute somehow?

Condor
1 Dec 2008, 2:40 AM
Your treepanel is missing the loader config option (loader: heatDs).

Dr. Flink
1 Dec 2008, 2:51 AM
Thanks for answering!

I added loader: heatDs, but the problem stays the same...

Some of the problems I have:
Checking a parent checkbox selects the children but the parent it self is not checked.
Unchecking one of the children unchecks all.
Cant check a single child if it has siblings.


var heatPanel = new Ext.Panel({
title: 'Statistik',
iconCls: 'iconStatistics',
layout:'border',
items: [
{
title: 'Fastigheter',
region:'west',
border: false,
width: 300,
layout: 'fit',
items: {
xtype: 'treepanel',
useArrows:true,
border: false,
rootVisible: false,
autoScroll: true,
root: heatRoot,
loader: heatDs
}
},
{
...
}
]
});

Condor
1 Dec 2008, 3:50 AM
I don't have any problems using the example with:

Ext.onReady(function(){
new Ext.Viewport({
layout:'fit',
items:[{
xtype: 'treepanel',
title: 'Tree checkbox test',
rootVisible: false,
autoScroll: true,
root: new Ext.tree.AsyncTreeNode(),
loader: new Ext.tree.TreeLoader({
url: 'tree.json',
preloadChildren:true,
baseAttrs:{
uiProvider: Ext.tree.TriStateNodeUI
}
})
}]
});
});
(where tree.json contains the content of the data variable)

Dr. Flink
1 Dec 2008, 4:31 AM
Yes, when I return this from the server:

$nodes[0]['text'] = 'Foo';
$nodes[0]['checked'] = null;
$nodes[0]['expanded'] = true;
$nodes[0]['children'][0] = array(
'text'=>'Child of foo 1',
'checked'=>true,
'leaf'=>true
);
$nodes[0]['children'][1] = array(
'text'=>'Child of foo 2',
'checked'=>true,
'leaf'=>true
);

$json = Zend_Json::encode($nodes);
$this->getResponse()->setBody($json);...it works fine. I think it's the "children"-option that makes it work.

Do I have to return all the nodes from start? I only want to load the children when necessary.
Now I return the following from the server:

[
{"id":"category_7","text":"Category 7","leaf":false,"expanded":false},
{"id":"category_8","text":"Category 8":false,"expanded":false}
]Expanding Category 8 makes the server return all that categorys customers:

[
{"id":"customer_96","text":"Customer 96","leaf":false,"checked":false,"disabled":false,"expanded":false}
]And, finaly, expanding Customer 96 will return that customers premises:

[
{"id":"premises_90","text":"Premises 90","leaf":true,"checked":false,"expanded":false,"iconCls":"iconPremises"},
{"id":"premises_91","text":"Premises 91","leaf":true,"checked":false,"expanded":false ,"iconCls":"iconPremises"},
{"id":"premises_92","text":"Premises 92","leaf":true,"checked":false,"expanded":false,"iconCls":"iconPremises"},
{"id":"premises_93","text":"Premises 93","leaf":true,"checked":false,"expanded":false,"iconCls":"iconPremises"}
]I'm not using the chidren attribute anywhere, is this the reason why its not working?

Condor
1 Dec 2008, 4:38 AM
You should at least remove the preloadChildren:true config option in that case.

Dr. Flink
1 Dec 2008, 4:43 AM
Yes, I allready tried setting it to false and removing it. Sorry for not mentioning.
But it seem to make no difference...

Condor
1 Dec 2008, 4:57 AM
What exactly is the problem?

When you check the customer and then expand it, it shows the premises as unchecked?

For that you should modify the beforeload handler, e.g.

var heatDs = new Ext.tree.TreeLoader({
url: '/member/statistics/heatTree',
baseAttrs:{
uiProvider: Ext.tree.TriStateNodeUI
},
listeners: {
beforeload: function(loader, node, callback) {
this.baseParams.depth = node.getDepth();
if(typeof node.attributes.checked == 'boolean'){
this.baseAttrs.checked = node.attributes.checked;
}else{
delete this.baseAttrs.checked;
}
}
}
});

Dr. Flink
1 Dec 2008, 5:15 AM
The problem is that the tree doesn't behave as it should when checking/unchecking nodes.

Tree structure:


Category 7
[ ]Customer 10
[ ]Premises 12
Category 8
[ ]Customer 96
[ ]Premises 90
[ ]Premises 91
[ ]Premises 92
[ ]Premises 93

1. I click checkbox on Premises 12. This will make the checkbox checked (but not the Customer 10 checkbox).
2. Then I click on premises 91 checkbox. Premises 12 will get unchecked and nothing happens to premises 91(!).

Its impossible to visually make any of the premises under Customer 96 checked (have siblings), but I can check Premises 12 (no siblings).
Visually, its impossible to make the customers checkboxes checked (probably because they also have siblings).

Condor
1 Dec 2008, 5:31 AM
Are you sure your node ids are unique?

Dr. Flink
1 Dec 2008, 5:35 AM
Yes, the id is an autoincremented primary key. I use "category_", "customer_" and "premises_" as a prefix.

Condor
1 Dec 2008, 6:03 AM
I can't reproduce your problem...

Is there a way you can make your example available on the internet?

Dr. Flink
1 Dec 2008, 7:03 AM
As I wrote some example code I found out what's causing the error.
I've removed the categories checkbox because I don't want the user to be able to select to many premises at once.

So, on the top parents (categories) I'm not using the checked -option.
Is there another way to remove the checkboxes on the top level nodes (categories)?

...here's the example code showing the problem:
example.html (my changes marked in bold)

<script type="text/javascript">
Ext.onReady(function(){
var heatDs = new Ext.tree.TreeLoader({
url: 'heatTree.php',
//preloadChildren:true,
baseAttrs:{
uiProvider: Ext.tree.TriStateNodeUI
},
listeners: {
beforeload: function(store, node, callback) {
this.baseParams.depth = node.getDepth();
}
}
});

var root = new Ext.tree.TreeNode({
//children:data
id: '0'
});
new Ext.tree.TreeLoader({
preloadChildren:true,
baseAttrs:{
uiProvider:Ext.tree.TriStateNodeUI
}
}).load(root);
new Ext.Viewport({
layout:'fit',
items:[{
xtype:'treepanel',
title:'Tree checkbox test',
rootVisible:false,
autoScroll:true,
root:root
}]
});

heatDs.load(root)
});
</script>heatTree.php


<?php

$depth = $_POST['depth'];
$node = substr($_POST['node'], 9);

switch($depth) {
case 0:
// Init tree, return categories
$nodes[0]['id'] = 'category_1';
$nodes[0]['text'] = 'Category 1';
//$nodes[0]['checked'] = false; // Remove comment to make it work as supposed
$nodes[0]['expanded'] = false;
$nodes[1]['id'] = 'category_2';
$nodes[1]['text'] = 'Category 2';
//$nodes[1]['checked'] = false; // Remove comment to make it work as supposed
$nodes[1]['expanded'] = false;
break;
case 1:
// A category have been chosen, return that categorys customers
if($node == 1) {
$nodes[0]['id'] = 'customer_1';
$nodes[0]['text'] = 'Customer 1';
$nodes[0]['checked'] = false;
$nodes[0]['expanded'] = false;
$nodes[1]['id'] = 'customer_2';
$nodes[1]['text'] = 'Customer 2';
$nodes[1]['checked'] = false;
$nodes[1]['expanded'] = false;
}
if($node == 2) {
$nodes[0]['id'] = 'customer_3';
$nodes[0]['text'] = 'Customer 3';
$nodes[0]['checked'] = false;
$nodes[0]['expanded'] = false;
$nodes[1]['id'] = 'customer_4';
$nodes[1]['text'] = 'Customer 4';
$nodes[1]['checked'] = false;
$nodes[1]['expanded'] = false;
}
break;
case 2:
// A customer have benn chosen, return that customers premises
if($node == 1) {
$nodes[0]['id'] = 'premises_1';
$nodes[0]['text'] = 'Premises 1';
$nodes[0]['checked'] = false;
$nodes[0]['leaf'] = true;
$nodes[1]['id'] = 'premises_2';
$nodes[1]['text'] = 'Premises 2';
$nodes[1]['checked'] = false;
$nodes[1]['leaf'] = true;
}
if($node == 2) {
$nodes[0]['id'] = 'premises_3';
$nodes[0]['text'] = 'Premises 3';
$nodes[0]['checked'] = false;
$nodes[0]['leaf'] = true;
$nodes[1]['id'] = 'premises_4';
$nodes[1]['text'] = 'Premises 4';
$nodes[1]['checked'] = false;
$nodes[1]['leaf'] = true;
}
if($node == 3) {
$nodes[0]['id'] = 'premises_5';
$nodes[0]['text'] = 'Premises 5';
$nodes[0]['checked'] = false;
$nodes[0]['leaf'] = true;
$nodes[1]['id'] = 'premises_6';
$nodes[1]['text'] = 'Premises 6';
$nodes[1]['checked'] = false;
$nodes[1]['leaf'] = true;
}
if($node == 4) {
$nodes[0]['id'] = 'premises_7';
$nodes[0]['text'] = 'Premises 7';
$nodes[0]['checked'] = false;
$nodes[0]['leaf'] = true;
$nodes[1]['id'] = 'premises_8';
$nodes[1]['text'] = 'Premises 8';
$nodes[1]['checked'] = false;
$nodes[1]['leaf'] = true;
}
}

$data = json_encode($nodes);
echo $data;

?>

Condor
1 Dec 2008, 8:22 AM
Yes, that's a really big bug you found.

You can fix it with:

Ext.override(Ext.tree.TriStateNodeUI, {
onCheckChange :function(){
Ext.tree.TriStateNodeUI.superclass.onCheckChange.apply(this, arguments);
var p = this.node;
while((p = p.parentNode) && p.getUI().updateParent && p.getUI().checkbox && !p.getUI().isUpdating) {
p.getUI().updateParent();
}
}
});

Dr. Flink
2 Dec 2008, 1:13 AM
Yes, it worked like a charm :).

Another issue:
When I'm loading children on-the-fly from the server, as I do (using preloadChildren: false), I want the children to be loaded and checked (without expanding the parent) when checking an unexpanded parent.

1. The categories is loaded.
2. I expand Category 1 (Customer 1 and Customer 2 becomes visible).
3. I check Customer 1 (without expanding it first).
4. I alert getChecked(). This should also alert the childrens of Customer 1...

Another question:
What is the best way to send checked boxes to the server?
I want to load a google chart image depending on what nodes is checked. When I'm clicking a parent node, checkchange will be fired multiple times. I need a listener that is being fired only once, when all children is checked/unchecked...

This ugly code is what I've come up with for the moment (resumeEvents() isn't doing what it should though...):

{
xtype:'treepanel',
title:'Tree checkbox test',
rootVisible:false,
autoScroll:true,
root:root,
listeners: {
checkchange: function(node, isChecked) {
var isParent = !node.isLeaf();
var checkedNodes = [];
if(isParent && isChecked) {
this.suspendEvents();
node.expand(true, true, function(node) {
node.cascade(function() {
if(!this.getUI().isChecked()) this.getUI().toggleCheck(true);
if(this.isLeaf()) checkedNodes.push(this.id);
});
alert(checkedNodes);
});
}
else this.resumeEvents();
}
}
}

Condor
2 Dec 2008, 2:20 AM
I think what you actually need is a way to set the check state of loaded children based on the checked state of the parent.

Try:

loader: new Ext.tree.Loader({
url: '...',
baseAttrs: {
uiProvider:Ext.tree.TriStateNodeUI
},
listeners: {
beforeload: function(loader, node, callback) {
if(node.attributes.checked !== undefined){
loader.baseAttrs.checked = node.attributes.checked;
} else {
delete loader.baseAttrs.checked;
}
}
}
}
(and your server should not return a checked attribute for premises)

Dr. Flink
2 Dec 2008, 2:49 AM
Yes, it renders the children checked when expanding the parent (customer). But it will not include the unrendered children (premises) using getChecked().

Somehow I must load the children when checking the parent (without expanding the parent), else the tree wont know anything about the children... :-?

(And, if I somehow can have some sort of a callback function or listener when all the children is finished being checked/unchecked, that would be heaven)

Dr. Flink
2 Dec 2008, 4:15 AM
Ok, I made the following changes, workes fine for my needs. It will store all checked leafs in an array (checkedLeafs). When a checkbox is clicked it will add leafs to the array and finally fire leafschange.
In other words: Checking a parent will expand the childrens, make them checked, adding them to the array and finally fire leafschange once.

Please, tell me if you have a better way doing this.


{
xtype:'treepanel',
title:'Tree checkbox test',
rootVisible:false,
autoScroll:true,
root:root,
checkedLeafs:[],
listeners: {
leafschange: function() {
alert(this.checkedLeafs);
}
}
}

Ext.override(Ext.tree.TreeNodeUI, {
onCheckboxClick:function() {
// My code
var isChecked = this.node.attributes.checked == null ? false : !this.node.attributes.checked;
var isParent = !this.node.isLeaf();

if(isParent) {
if(isChecked && !this.node.isExpanded()) {
this.node.expand(true, true, function(node) {
node.cascade(function() {
if(!this.getUI().isChecked()) this.getUI().toggleCheck(true);
if(this.isLeaf() && this.ownerTree.checkedLeafs.indexOf(this) < 0) this.ownerTree.checkedLeafs.push(this);
});
node.ownerTree.fireEvent('leafschange', this);
});
}
else {
var i = 0;
this.node.cascade(function(node) {
if(node.isLeaf()) {
if(isChecked) this.node.ownerTree.checkedLeafs.push(node);
else this.node.ownerTree.checkedLeafs.remove(node)
}
if(i == this.node.childNodes.length) this.node.ownerTree.fireEvent('leafschange');
i++;
}, this);
}
}
else {
isChecked ? this.node.ownerTree.checkedLeafs.push(this.node) : this.node.ownerTree.checkedLeafs.remove(this.node);
this.node.ownerTree.fireEvent('leafschange');
}
// End of my code

if(!this.disabled){
this.toggleCheck();
}
}
});

Condor
2 Dec 2008, 4:36 AM
Can't you use the checkchange (http://extjs.com/deploy/dev/docs/?class=Ext.tree.TreePanel&member=checkchange) event for that?

Dr. Flink
2 Dec 2008, 5:35 AM
Checkchange was the first thing I tried. The reason I went with onCheckboxClick was to know what box was clicked from within the event.
And I think the checkchange event is acting inconsistently when unchecking boxes.


[ ] Grandparent
[ ] Parent
[ ] Leaf 1
[ ] Leaf 2
[ ] Leaf 3
[ ] Leaf 4When I check Leaf 2, the checkchange will fire twice (Parent and Leaf 2), correctly.
But, when I uncheck Leaf 2 it will fire 6 times(!). Twice for Leaf 2 and once for each node (Parent, Leaf 1, Leaf 3, Leaf 4).

onCheckboxClick fires only once. And I can easily see if the node is a parent and what nodes should be added into/removed from the array.

Please, tell me if I've missed something using the checkchange event.

Condor
2 Dec 2008, 6:53 AM
There should be an extra check in onCheckChange:

Ext.override(Ext.tree.TreeNodeUI, {
onCheckChange :function(){
var checked = this.isChecked();
if(checked !== this.node.attributes.checked){
this.node.attributes.checked = checked;
this.fireEvent('checkchange', this.node, checked);
}
}
});

after which you could use:

listeners:{
checkchange: function(node, checked){
if(!node.isLeaf()){
node.expand();
}
}
}

cruisin
3 Dec 2008, 9:41 PM
thanks for the contribution

when I turned on DD with enableDD:true, I am unable to rearrange nodes via DD
as is possible in the original Tree

am I missing something ?

thx

starmage
8 Dec 2008, 4:35 AM
great job with that tri-state Tree :D

But i agree with cruisin and when i'm enableDD, i have some trouble with the firefox. I start the drag and everything works fine until i want to drag the node anywhere. If i release the button nothing happens and it freeze the drag, so i could not end the drag.

In Internet Explorer everything works ok.

Do i forget anything?

Thx

PSB
17 Dec 2008, 7:35 AM
Please replace archive after last override.

Thanks..

Condor
17 Dec 2008, 7:48 AM
Please replace archive after last override.
I updated the original post to version 1.2 (not many changes, except one nasty bugfix).

snoir
17 Dec 2008, 5:48 PM
i downlaod it ,but no checkbox on tree

Condor
17 Dec 2008, 9:43 PM
The TreeCheckbox.css file contains a reference to the checkbox.gif file. Make sure it points to the correct file if you put the example in a different directory.

Frenky
18 Dec 2008, 10:45 PM
excellent!!

it works perfect for me

snoir
23 Dec 2008, 3:19 AM
The TreeCheckbox.css file contains a reference to the checkbox.gif file. Make sure it points to the correct file if you put the example in a different directory.
thx,the demo is right~:))

jwignall
11 Feb 2009, 2:41 AM
Just FYI, you left a console line(212) in TreeCheckbox.js

console.log(this.getNodeTarget(e));

jwignall
12 Feb 2009, 2:13 AM
I was just wondering why the AsynchTriStateNodeUI isn't the default behaviour in all cases?

I was puzzling for a while about why child checkboxes weren't checked when the parent is checked unless the parent had been expanded at least once. Is there a case where you would not want the child nodes to be toggled when a parent is toggled?

Juel
16 Feb 2009, 4:17 AM
Hi,

I just detected a bug using the TriStateTree version 1.2..
By including the TreeCheckbox.js into a index.html - the on('click') and some other events don't fire anymore - even when using just a normal tree without TriState checkboxes.

This is related with my Post here (http://extjs.com/forum/showthread.php?t=59987&highlight=click+dblclick):
Here's some example code:

applayout.js:



Ext.onReady(function(){

var data = [{
//id:'a',
text:'A',
leaf:true
},{
//id:'b',
text:'B',
leaf:true
}];

var tree = new Ext.tree.TreePanel({
width: 550,
height: 300,
rootVisible:false,
autoScroll:true,
title: 'TreeClickExample',
renderTo: Ext.getBody(),

loader: new Ext.tree.TreeLoader({
}),

root: new Ext.tree.AsyncTreeNode({
children:data
})
});

tree.on('click', function(n){
alert('click');
});
//tree.on('dblclick', function(n){
// alert('dblclick');
//});

});

index.html:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="ext-2.2/resources/css/ext-all.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/TreeCheckbox.css" media="screen" />
<link rel="stylesheet" type="text/css" href="stylesheets/TriStateNodeUI.css" media="screen" />
<script type="text/javascript" src="ext-2.2/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-2.2/ext-all-debug.js"></script>
<script type="text/javascript" src="javascripts/TreeCheckbox.js"></script>
<script type="text/javascript" src="javascripts/TriStateNodeUI.js"></script>
<script type="text/javascript" src="applayout.js"></script>
<title>TreeExample</title>
</head>
<body>

</body>
</html>
By removing the line:
<script type="text/javascript" src="javascripts/TreeCheckbox.js"></script> from index.html - the onclick event fires, but this is also browser specific:

With TreeCheckbox.js included, the on('click') seems to work in Firefox 2.0.0.18
but not in Opera 9.62 Konqueror 3.5.5, IE 6.0.3790.3959 and Firefox 3.
The on('dblclick') event seems to work in all five of them.

I attached a full example of my code including the latest ext - version here (http://msg2.me/Archiv.zip):

NaveenMinchu
4 Mar 2009, 10:30 PM
We could see console.log() which is debuging script at line 212 of TreeCheckbox.js which is causing some problem in IE when we use listeners for TriStateCheckbox sampple page.

Do we require console.log() in TreeCheckbox.js ?

Condor
4 Mar 2009, 10:37 PM
No, sorry, I left that line in by mistake. You can safely remove it.

NaveenMinchu
8 Mar 2009, 3:43 AM
Hi,

Can we please know what can we expect from the widget in terms of pros (working) and cons(non-working) stuff of the current Tri-state widgets.

Between the this.emptyIcon in the renderElements function (At line 78) in the TreeCheckbox.js is pointing to "http://www.extjs.com/s.gif" which will obviously cause problems when the end-user using the widget is offline.

Excpeting your reply on pros and cons.

Appreciate your response.

Regards,
Naveen

Condor
8 Mar 2009, 1:12 PM
Between the this.emptyIcon in the renderElements function (At line 78) in the TreeCheckbox.js is pointing to "http://www.extjs.com/s.gif" which will obviously cause problems when the end-user using the widget is offline.

Did you read the first item (http://extjs.com/learn/Ext_FAQ#My_code_links_to_extjs.com.2Fs.gif) of the Ext JS FAQ?

Raz0r
16 Mar 2009, 12:30 PM
Hi!
I've extended this plugin to display columns like in sample ColumnTree (http://extjs.com/deploy/dev/examples/tree/column-tree.html).
Everything is the same except the names: ColumnCheckboxTree for TreePanel, ColumnCheckboxNodeUI for TriStateNodeUI and AsynchColumnCheckboxNodeUI for AsynchTriStateNodeUI.
Greets!

NaveenMinchu
24 Mar 2009, 10:01 PM
Hi,

Can you please let us know why even we are setting rootVisible:'false' is showing root on UI,
when we are using Tri-stateCheckBox tree with TreeLoader

It is important for us, please let us know.

Appreciate your help :)

Thanks & Regards,
Naveen

aj3423
12 May 2009, 12:38 AM
Agree with starmage, in FireFox, drag a node then release mouse, it freezes the drag, I commented some code to fix that, it works.

delegateUp : function(e, t) {
// if(!this.beforeEvent(e)) { // comment these 3 line
// return;
// }
if(e.getTarget('.x-tree-checkbox', 1)) {
this.onCheckboxUp(e, this.getNode(e));
}
},

Antjac
8 Jun 2009, 5:04 AM
Hi, Thx for your component,

I've just a little problem due to (I think) the fact, that is it a asynctree.
When i check a node and if the children nodes are'nt expanded, the children will be not check.

Do you have any idea to automatically check the children of a unexpended parent ?


Thx,

Antoine

jbum
11 Jun 2009, 8:57 AM
Have others been able to use "rootVisible: false" to hide the root node? The root node is still visible for me but it's now laid out without any indentation for the child nodes - root and child nodes look like they are part of the same level in the tree.

Help please.

nintondo
12 Jul 2009, 10:52 AM
unable to get checkboxes showing..using ffox 3.5

Condor
12 Jul 2009, 11:13 PM
unable to get checkboxes showing..using ffox 3.5

And you did adjust the path to the images in the .css file?

Lobos
16 Jul 2009, 6:10 PM
Nice work man! works great!

I am trying to tirgger the load spinner to come up in beside the node because I do the node checked state save on each check. so bascially I am looking to show the user that soemthign is going on when they check or uncheck...

Condor
16 Jul 2009, 10:54 PM
Nice work man! works great!

I am trying to tirgger the load spinner to come up in beside the node because I do the node checked state save on each check. so bascially I am looking to show the user that soemthign is going on when they check or uncheck...

Use:

node.getUI().beforeLoad();
and

node.getUI().afterLoad();
to show and hide the loading indicator.

treilor
13 Aug 2009, 4:56 AM
Thank you for extension!

I've noticed some strange behaviour using AsynchTreeNode.
Having tree structure like that:


[ ] Node 1
[ ] Node 1.2
[ ] Node 1.2.1
[ ] Node 1.2.2
[ ] Node 1.2
Tree nodes are properly (I believe) configured with AsynchTriStateNodeUI. When I check Node 1.2, Node 1.2.1 and Node 1.2.2 are checked as well. Then if I uncheck Node 1.2.1, Node 1.2 and 1.2.2 get unchecked, but 1.2.1 still shown as checked (like it wasn't internally "checked" on checking its parent).

Adding call to a parent method in AsynchTriStateNodeUI.updateChild() fixes the problem:


updateChild:function(checked){
if(this.checkbox){
if(checked === true){
Ext.fly(this.ctNode).replaceClass('x-tree-branch-unchecked', 'x-tree-branch-checked');
} else if(checked === false){
Ext.fly(this.ctNode).replaceClass('x-tree-branch-checked', 'x-tree-branch-unchecked');
} else {
Ext.fly(this.ctNode).removeClass(['x-tree-branch-checked', 'x-tree-branch-unchecked']);
}
}
Ext.tree.AsynchTriStateNodeUI.superclass.updateChild.apply(this, arguments);
},Am I correct or just missing something?

Eric24
6 Sep 2009, 10:47 PM
@Condor - This looks great. Is it compatible with Ext 3.0?

Condor
6 Sep 2009, 10:51 PM
@Condor - This looks great. Is it compatible with Ext 3.0?

I haven't used it on an Ext 3.0.0 project yet. If it isn't compatible then I don't expect that it requires big changes (TreePanel hasn't changed very much from 2.x to 3.x).

dayrl
10 Sep 2009, 5:26 PM
how can I set the item's check state by script?
I mean there's two trees,the second tree contains options that cat set the first tree's check state.

rosslai
4 Oct 2009, 7:32 PM
Dear Condor

I can't find any resourse about tri-state tree in Ext 1.1.
Could this script be used in Ext 1.1? or can you guide me to modify this script to fit in Ext 1.1?

kwatanabe
5 Oct 2009, 8:07 AM
Is there any solution for this problem. The tri-state tree is broken unless the unopened parent functionlity is fixed.

asyura
19 Jan 2010, 4:16 PM
if use in 3.1, the tree will not work with drapdrop, can you fix it.

Dumas
20 Mar 2010, 9:45 AM
I would like to use that tree so that users can check what they want to copy to another destination, so it's a file tree.

Therefore I have an unwanted behaviour, because it's hard to display, I made a short screencast where you can perfectly see it:
www.screencast.com/t/NjI5NmYxZ

What would I have to adjust?

thx a lot
Roland

Lobos
29 Mar 2010, 6:47 AM
Agree with starmage, in FireFox, drag a node then release mouse, it freezes the drag, I commented some code to fix that, it works.

delegateUp : function(e, t) {
// if(!this.beforeEvent(e)) { // comment these 3 line
// return;
// }
if(e.getTarget('.x-tree-checkbox', 1)) {
this.onCheckboxUp(e, this.getNode(e));
}
},

This fixed my problem - I was using the drag and drop between two trees example and the tristate tree was causing a bug where you could drag and drop from one tree to antoher, but if you tried in the same tree it would freeze and not drop the item.

Maybe this fix should be added to the distro?

Thanks!

Capt.JackSparrow
9 Dec 2010, 11:48 PM
Hi Condor,
FOA, Thanks for the wonderful extension.
I am using AsynchTristateNodeUI as below:
The problem is during render I literally need to expand and collapse nodes to make the
parent node checkboxes checked.
This severely impacts the performance, lot in IE.
Is there a clean way to load the parent node checkboxes correctly.



Bm.util.CheckTreePanel = Ext.extend(Ext.tree.TreePanel, {
config : {},
chkTreeRoot : null,
getTreePanelRoot : function() {
if(Ext.isEmpty(this.chkTreeRoot)) {
var root = new Ext.tree.TreeNode({
children : this.config.data
});
this.chkTreeRoot = root;
}
return this.chkTreeRoot;
},
getTreeLoader : function() {
var treeLoader = new Ext.tree.TreeLoader({
preloadChildren:true,
baseAttrs:{
uiProvider:Ext.tree.AsynchTriStateNodeUI
}
}).doPreload(this.getTreePanelRoot());
return treeLoader;
},
constructor : function(config) {
this.config = config;
if(!this.isValidConfig()) {
return;
}
var panelConfig = {
root : this.getTreePanelRoot(),
loader : this.getTreeLoader(),
listeners : {
}
};
Ext.apply(panelConfig, config, this.getDefaultValues());
panelConfig = this.addContextMenu(panelConfig);
this.config = panelConfig;
Bm.util.CheckTreePanel.superclass.constructor.call(this, this.config);
},

getDefaultValues : function() {
var defaultValues = {
title : '',
useArrows : true,
autoScroll : true,
animate : true,
enableDD : false,
containerScroll : true,
rootVisible : false,
expandRootNode : true,
border : false,
header : false,
enableContextMenu : true
};
if(Ext.isEmpty(this.config.height)) {
defaultValues.autoHeight = true;
} else {
defaultValues.height = this.config.height;
}

if(!Ext.isEmpty(this.config.width)) {
defaultValues.width = this.config.width;
}
return defaultValues;
},

isValidConfig : function() {
//mandatory values
if(isInvalidValue(this.config.id, "id")) {
return false;
}
if(isInvalidValue(this.config.renderTo, "renderTo")) {
return false;
}
if(isInvalidValue(this.config.data, "data")) {
return false;
}
return true;
},

render : function() {
Bm.util.CheckTreePanel.superclass.render.apply(this, arguments);
this.expandAll();
Ext.each(this.getRootNode().childNodes, function(node){
node.collapse(true);
node.expand(false);
});
},

getSelectedItems : function() {
var selNodes = this.getChecked();
var sel = {};
var tmp = {};
Ext.each(selNodes, function(node){
var nodeId = getNodeId(node);
if(node.hasChildNodes()) {
var parent = node.parentNode;
if(parent) {
var parentNodeId = getNodeId(parent);
if(sel[parentNodeId] != "all"
&& tmp[parentNodeId] != "sibling-not-all") {
sel[nodeId] = "all";
if(!Ext.isEmpty(parentNodeId)) {
sel[parentNodeId] =
getCommaSepStr(sel[parentNodeId], nodeId);
}
} else {
tmp[nodeId] = "sibling-not-all";
}
} else {
sel[nodeId] = "";
}
} else {
var parent = node.parentNode;
if(parent) {
if(sel[getNodeId(parent)] != "all") {
if(tmp[getNodeId(parent)] != "sibling-not-all") {
var childId = nodeId;
do {
sel[getNodeId(parent)] =
getCommaSepStr(sel[getNodeId(parent)], childId);
childId = getNodeId(parent);
parent = parent.parentNode;
} while(parent && !Ext.isEmpty(getNodeId(parent)))
sel[nodeId] = "yes";
}
}
}
}
})
return sel;
},

addContextMenu : function(panelConfig) {
if(panelConfig.enableContextMenu) {
var contextMenu = {
contextMenu: new Ext.menu.Menu({
items: [{
id: 'selectAll',
text: 'Select All'
}, {
id: 'deselectAll',
text: 'DeSelect All'
}, {
id: 'expand',
text: 'Expand'
}, {
id: 'collapse',
text: 'Collapse'
}, {
id: 'expandAll',
text: 'Expand All'
}, {
id: 'collapseAll',
text: 'Collapse All'
}],
listeners: {
itemclick: function(item) {
switch (item.id) {
case 'selectAll':
var n = item.parentMenu.contextNode;
toggleCheck(n, true);
n.expand(true);
break;
case 'deselectAll':
var n = item.parentMenu.contextNode;
toggleCheck(n, false);
n.expand(true);
break;
case 'expand':
var n = item.parentMenu.contextNode;
n.expand(false);
break;
case 'collapse':
var n = item.parentMenu.contextNode;
n.collapse(false);
break;
case 'expandAll':
var n = item.parentMenu.contextNode;
n.expand(true);
break;
case 'collapseAll':
var n = item.parentMenu.contextNode;
n.collapse(true);
break;
}
}
}
})
}
var contextMenuListener = {
contextmenu : function(node, e) {
if(!node.isLeaf()) {
node.select();
var c = node.getOwnerTree().contextMenu;
c.contextNode = node;
c.showAt(e.getXY());
}
}
};
Ext.applyIf(panelConfig, contextMenu);
Ext.applyIf(panelConfig.listeners, contextMenuListener);
};
return panelConfig;
}
});


Thanks!

maitreya.karandikar
17 Oct 2012, 1:36 AM
Condor

We are facing issues using tristate check box tree with ext-js 4.1.1.
There is no ext-base.js script . Is there an updated version to go with ext-js 4.1.1 ?




Ext 2.2 introduced a themed checkbox component, but unfortunately the new checkbox theme wasn't used for trees and fieldsets.

So I started out making a TreeNodeUI that would use checkbox images instead of checkbox inputs.
After I finished I couldn't resist making a TreeNodeUI descendant that would do what many of you have asked for: support checkboxes with a grayed/partial state and automatic cascading.

Include TreeCheckbox.css and TreeCheckbox.js to get themed checkboxes in your grid.

Include TriStateNodeUI.css and TriStateNodeUI.js and set the uiProvider to TriStateNodeUI to get automatic update of parent/child checked states.
If your tree is very large or if you are using asynchronous node loading (AsynchTreeNode) you should use AsynchTriStateNodeUI instead of TriStateNodeUI (because children that aren't loaded yet can't be checked/unchecked).

Check out example.html to see how to use the new components.

Version 1.1:
- Removed CSS margin.
- Added getChecked method to return correct checked state, even with AsynchTriStateNodeUI.
- Changed TriStateNodeUI to do a real check cascade and moved the original virtual cascading code to AsynchTriStateNodeUI, to be used when a real cascade is to slow (large tree) or impossible (asynchronous node loading).

New version 1.2:
- Fixed bug when in mixing nodes with and without checkboxes.
- Only fire checkchange if checked stated actually changed.

buy sustanon
28 Jan 2013, 2:08 AM
J'ai juste besoin de savoir comment obtenir un site web a commencé. Je veux faire un site de fan pour un nouveau groupe. Je sais que je dois payer pour un domaine, mais je suis confus sur la façon d'acheter et construire un site web. Aidez s'il vous plaît? Merci d'avance! (: Merci à tous. (!:.