PDA

View Full Version : TreePanel - Selecting all relative nodes (parents & children) when a node is selected



primolan
26 Nov 2009, 4:10 AM
Hello!

I made some functions to select all children (and its children - recursive) and all parents (and its parents - recursive) when a node is selected.

Here are the functions:



/**
* Select all parents nodes from specified node (recursive, getting parents' parents and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var selectParents = (function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.parentNode) {
selModel.select(node.parentNode, null, true);
selectParents(node.parentNode);
}
});

/**
* Unselect all parents nodes from specified node (recursive, getting parents' parents and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var unselectParents = (function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.parentNode) {
if (node.parentNode.hasChildNodes()) {
selChild = 0;
node.parentNode.eachChild(function(child){
if (!child.isSelected()) selChild++;
});
if (selChild == node.parentNode.childNodes.length) {
selModel.unselect(node.parentNode);
}
} else {
selModel.unselect(node.parentNode);
}
unselectParents(node.parentNode);
}
});

/**
* Select all children nodes from specified node (recursive, getting children's children and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var selectChild = (function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.hasChildNodes) {
node.eachChild(function(child){
selModel.select(child, null, true);
selectChild(child);
});
}
});

/**
* Unselect all children nodes from specified node
*
* @param Ext.data.node Node
* @return void
*/
var unselectChild = (function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.hasChildNodes) {
node.eachChild(function(child){
selModel.unselect(child);
unselectChild(child);
});
}
});

/**
* Select specified node, its parent and children (and forward)
*
* @param Ext.data.node Node
* @return void
*/
var selectNode = (function(node){
selModel = node.getOwnerTree().getSelectionModel();
selModel.select(node, null, true);
selectChild(node);
selectParents(node);
});

/**
* Unselect specified node, its parent and children (and forward)
*
* @param Ext.data.node Node
* @return void
*/
var unselectNode = (function(node){
selModel = node.getOwnerTree().getSelectionModel();
selModel.unselect(node);
unselectChild(node);
unselectParents(node);
});


How to use it? Create a listener to CLICK event on TreePanel:



listeners: {
click: function(node, event) {
selModel = node.getOwnerTree().getSelectionModel();
if (node && node.text != 'rootNode') {
if (node.isSelected()) {
unselectNode(node);
} else {
selectNode(node);
}
return false;
}
},
scope: this
}


I hope that some day, this would be an option in TreePanel, like "selectRelatives: true|false" .. I also hope you guys enjoy it.

And if someone know a better way to do these, please share it!

Cya!

jbo87
2 Dec 2009, 4:54 AM
Don't see any use case where i could need this. But i put it into a plugin b/c thats where something like this belongs ;)
Anyways: I haven't looked into the logic of your code. So i just copied the code into the plugin.



Ext.namespace('Ext.ux.tree');
Ext.ux.tree.RelativeSelectPlugin=function () {
/**
* Select all parents nodes from specified node (recursive, getting parents' parents and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var selectParents = function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.parentNode) {
selModel.select(node.parentNode, null, true);
selectParents(node.parentNode);
}
};

/**
* Unselect all parents nodes from specified node (recursive, getting parents' parents and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var unselectParents = function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.parentNode) {
if (node.parentNode.hasChildNodes()) {
selChild = 0;
node.parentNode.eachChild(function(child){
if (!child.isSelected()) selChild++;
});
if (selChild == node.parentNode.childNodes.length) {
selModel.unselect(node.parentNode);
}
} else {
selModel.unselect(node.parentNode);
}
unselectParents(node.parentNode);
}
};

/**
* Select all children nodes from specified node (recursive, getting children's children and keep going till end)
*
* @param Ext.data.node Node
* @return void
*/
var selectChild = function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.hasChildNodes) {
node.eachChild(function(child){
selModel.select(child, null, true);
selectChild(child);
});
}
};

/**
* Unselect all children nodes from specified node
*
* @param Ext.data.node Node
* @return void
*/
var unselectChild = function(node) {
selModel = node.getOwnerTree().getSelectionModel();
if (node.hasChildNodes) {
node.eachChild(function(child){
selModel.unselect(child);
unselectChild(child);
});
}
};

/**
* Select specified node, its parent and children (and forward)
*
* @param Ext.data.node Node
* @return void
*/
var selectNode = function(node){
selModel = node.getOwnerTree().getSelectionModel();
selModel.select(node, null, true);
selectChild(node);
selectParents(node);
};

/**
* Unselect specified node, its parent and children (and forward)
*
* @param Ext.data.node Node
* @return void
*/
var unselectNode = function(node){
selModel = node.getOwnerTree().getSelectionModel();
selModel.unselect(node);
unselectChild(node);
unselectParents(node);
};

var onClick=function (node,event) {
selModel = node.getOwnerTree().getSelectionModel();
if (node && node.text != 'rootNode') {
if (node.isSelected()) {
unselectNode(node);
} else {
selectNode(node);
}
return false;
}
};


return {
init: function (tree) {
tree.addListener('click',onClick,tree);
}
}
}


to use it:


new Ext.tree.TreePanel({ plugins: new Ext.ux.tree.RelativeSelectPlugin(), root: ... });


note: make sure ur tree is using Ext.tree.MultiSelectionModel()

primolan
2 Dec 2009, 5:10 AM
Hi jbo87!

I used this on a perms' menu built on a tree. Instead using checkboxes, I wanted to keep all items selected, including their parents and childs.

The tree nodes was based on modular structure: module, controller, action. So, modules and controllers didn't have an ID, only action.

+ module 1
+ controller 1.1
action 1.1.1 - ID = 1
action 1.1.2 - ID = 2
+ controller 1.2
action 1.2.1 - ID = 3

Choosing an action, system automatically selects parents and childs. The point is: when a parent is selected, all childs should also be selected. This script do that only when a parent is clicked with an event (onClick), not when it's selected by script's routine.

Well, this is it!

And thanks very much for you help building a plugin! (I didn't test it yet, but will soon!)

Cya!

\:D/