PDA

View Full Version : Tree with Checked Checkboxes



DeDarling
3 Nov 2010, 7:49 AM
Hi,

im realy new to Ext JS.

I have an TreePanel with Checkboxes.

And now i would set the root checkbox as readonly.

But how .. ?

I tried many configuations but by the most i get a stack overflow error ?!?!?

Then i tried on every change on the root element to set the checked value = true but this dont work to...
What is my fault ?

My Code


function toggleCheck(node,isCheck)
{

if(node.isLeaf() != true) // nur bei RootElementen
{
//Ext.Msg.show({title: 'dsfdsf'})
node.attributes.checked = true;

}
/*
else
{
if(node)
{
//node.expand();
node.eachChild(function(n) {
n.eachChild(function(n1) {
toggleCheck(n1, isCheck);
});

n.getUI().toggleCheck(isCheck);

this.attributes.checked = isCheck;
if(isCheck)
n.getUI().show();
});
}
}*/
}

Ext.onReady(function(){

var tree = new Ext.tree.TreePanel({
title: 'Marketintelligence Merkmals Auszählung',
autoScroll: true,
animate: true,
enableDD: false,
containerScroll: true,
dataUrl: 'data.json.php',
width: 250,
height: 700,

root: {
nodeType: 'async',
text: 'Merkmale',
draggable: false,
id: '0'
},
listeners:
{
'checkchange': function(node, checked){
if(checked)
var tree = toggleCheck(node,true);
else
var tree = toggleCheck(node,false);
}
},
buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

// render the tree
tree.render('tree-div');
tree.getRootNode().expand();
});

Condor
3 Nov 2010, 7:53 AM
Do you actually need a root checkbox? If you don't need one then just don't give it a 'checked' attribute.

DeDarling
3 Nov 2010, 8:01 AM
oh sry i explained it wrong.

with root i mean the node with child nodes ...

If I deselect some of the child elements, the root element still selected
but stay in a different style. I tried to give the root element an readonly value but this dont works ...

Condor
3 Nov 2010, 8:11 AM
So you want a cascading checkbox tree! There are user extensions for that.

DeDarling
3 Nov 2010, 10:40 PM
Oh Ok .. thx ...

I search a while on many sites .. but i dont find something like Ext JS Cascading Checkbox .. :-(

Did you have a url ?

Condor
3 Nov 2010, 11:29 PM
Here is one (http://checktree.extjs.eu/).

DeDarling
3 Nov 2010, 11:49 PM
Ok sorry my English is to bad .. :-) Can you speak German ? :-) *smile*

Your Post is not what i want ...

My Tree
+Tools
|-+Tool1
|---Tool1.1
|---Tool1.2
|---Tool1.3
|-+Tool2

....

All Items are Checked ... but i want Node Tool1 as Readonly ....
and my 2. want is that min. 1 from the child nodes must leave checked ...

Condor
4 Nov 2010, 12:04 AM
I don't quite understand what you want...

Could you ask your question in German (I have no problem understanding German, just don't ask me to write it).

DeDarling
4 Nov 2010, 12:20 AM
Hey das ist schön :-)

Also, nochmal auf Deutsch :-)

Alle Nodes, Child Nodes starten gecheckt.

Mein TreePanel
+Tools
|-+Tool1
|---Tool1.1
|---Tool1.2
|---Tool1.3
|-+Tool2

1.
Ich möchte das die Checkbox von Node "Tool1", "Tool2" immer gecheckt ist und man darf sie nicht "deselektieren" können. In HTML kenne ich die "readonly" Eigentschaft.
Aber die kriege ich bei diesen Checkboxen nicht gesetzt.

I tried
'load' : function(node) {
node.ui.checkbox.readonly = true;

}


2.
Es muss mindestens eine der Child Nodes immer Selektiert bleiben .. also man darf nicht alle deselektieren.

So, and now please answer in German *smile* :D:D

Condor
4 Nov 2010, 12:24 AM
1. node.ui.checkbox is a real <input type="checkbox"> and HTML doesn't support a readonly attribute on this kind of element. The only thing you can do is disable the checkbox or modify the toggleCheck method to only change the checkbox when it is allowed.

2. Yet another thing you can only do from the toggleCheck method.

DeDarling
4 Nov 2010, 12:42 AM
Ich such mir einen Wolf :-( kannst du mir ein kleines Beispiel geben bitte ?

DeDarling
4 Nov 2010, 12:50 AM
I tried,


listeners:
{
'toggleCheck' : function(node){
if(node.isLeaf() != true) // nur bei RootElementen
{
node.checked = true;
}
}


but this dont works ...
In Germany we say "Ich bin verdammt nochmal auf dem Holzweg" :-(

steffenk
4 Nov 2010, 12:51 AM
Du kannst es auch im checkchange event machen, Beispiel:


listeners: {
'checkchange': function(checkedNode, checked) {
this.suspendEvents();
if (checkedNode.id === 'id120' && checked === false) {
checkedNode.attributes.checked = false;
checkedNode.ui.toggleCheck(true);
}
this.resumeEvents()
},
scope: this
}

DeDarling
4 Nov 2010, 12:55 AM
Hi Steffen.. danke für die Antwort.

Ich kriege den Fehler (this.suspendEvents();)
Fehler: Das Objekt unterstützt diese Eigenschaft oder Methode nicht.

und du hast dort id120 eingegeben ... öhm ist das was extjs internes ? ne oder ? Wie kriege ich denn da die id des deselektierten nodes her ?

Condor
4 Nov 2010, 12:57 AM
Example:

MyTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
toggleCheck : function(value){
var cb = this.checkbox;
if(cb){
var checked = (value === undefined ? !cb.checked : value);
if (this.node.isLeaf()) {
// Don't allow leaf to be unchecked if no other siblings are checked
if (!value && this.node.parentNode) {
var hasOtherChecked = false;
this.node.parentNode.eachChild(function(node){
if (node !== this.node && node.getUI().isChecked()) {
hasOtherChecked = true;
return false;
}
}, this);
if (!hasOtherChecked) {
value = true;
}
}
} else (
// Branches are read-only
value = this.node.attributes.checked;
}
cb.checked = checked;
this.onCheckChange();
}
}
});


...
loader: new Ext.tree.TreeLoader({
uiProviders: {mynode: MyTreeNodeUI},
baseAttrs: {uiProvider: 'mynode'},
...
})
Disclaimer: Completely untested code!

steffenk
4 Nov 2010, 1:04 AM
Condors Lösung ist besser da sie vor dem check greift. Leider muss man das mit einem override machen, und da muss man schon genau wissen was man macht um nicht vorhandene Funktionalität zu kappen.
Daher habe ich Dir die Lösung mit dem vorhandenen checkchange listener, wichtig ist das scope:this, um den tree im this zu haben.
Ok, now switch to english again :)

DeDarling
4 Nov 2010, 1:55 AM
HEy cool thx booth of you !

It works ... :-)

Jetzt muss ich nur noch einbauen das mindestens ein child node eines Nodes gechecket bleiben muss.

steffenk
4 Nov 2010, 2:03 AM
little example what i do (exclusiveKeys are keys which only allow to be checked alone)


if (checked === true && exclusiveKeys.indexOf(checkedNodes.attributes.uid) > -1) {
// this key is exclusive, so uncheck all others
this.root.cascade(function(node) {
if (node !== checkedNode && node.attributes.checked) {
node.attributes.checked = false;
node.ui.toggleCheck(false);
}
});
this.exclusiveSelectedKey = checkedNodes.attributes.uid;
}

cascade iterates through all nodes.

DeDarling
4 Nov 2010, 5:24 AM
Hi,

my complete Script with your help.


Ext.onReady(function(){

var tree = new Ext.tree.TreePanel({
title: 'Marketintelligence Merkmals Auszählung',
autoScroll: true,
animate: true,
enableDD: false,
containerScroll: true,
dataUrl: 'data.json.php',
width: 250,
height: 700,

root: {
nodeType: 'async',
text: 'Merkmale',
draggable: false,
id: '0'
},
listeners:
{
'checkchange': function(checkedNode, checked) {
if (checked === false) {
if(checkedNode.isLeaf() != true) // nur bei RootElementen
{
checkedNode.attributes.checked = false;
checkedNode.ui.toggleCheck(true);
}

var count = 0;
checkedNode.parentNode.eachChild(function(child){
if (child.getUI().isChecked()) {
count++;
}
});

if(count == 0) {
checkedNode.attributes.checked = false;
checkedNode.ui.toggleCheck(true);
}
}
},
scope: this
},
buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

// render the tree
tree.render('tree-div');
tree.getRootNode().expand();
});

Thx .. this Post can be closed :-)

steffenk
4 Nov 2010, 5:33 AM
you have to deactivate events in checkchange otherwise you get recursions

//begin
this.suspendEvents();

//end
this.resumeEvents();