PDA

View Full Version : Ext.ux.TreeMenu



NeonMonk
15 Dec 2008, 11:20 PM
Hi,
Demo (http://99thmonkey.org/extjs/examples/treemenu/index.html)

I've just finished building an extension to the TreePanel to make it more 'menuey' and easier to add, move, remove and map items.

The treemenu uses a 'hierarchy' system i.e.:

First MenuNode (not counting the invisible rootnode) is [0].
Its first child would be [0,0]
Second child would be [0,1].
The next MenuNode would be [1] and so on.

iconSize:
'small' : 16px
'medium' : 24px
'mediumlarge' : 48px
'large' : 64px


------------------------------------------------------------------------------------------------------------------------

Unfortunately I've encountered some bugs with IE6 and using 'within' with the mouseout feature, this has seemed to 'fix' the problem, but you may not want to go down that path.

Bug link: http://extjs.com/forum/showthread.php?t=55208

Quick "fix":

Ext.lib.Event.getRelatedTarget = function(M) {
M = M.browserEvent || M;
var L = M.relatedTarget;
if (!L) {
if (Ext.isIE) { return false; }
if (M.type == "mouseout") {
L = M.toElement
} else {
if (M.type == "mouseover") {
L = M.fromElement
}
}
}
return this.resolveTextNode(L)
};

The quick fix is already at the top of Ext.ux.TreeMenu.js -- so if you find the fix breaks something you can take it out (please post back here if it does).

NeonMonk
15 Dec 2008, 11:45 PM
Usage:

Constructing the menu is done by using the items property, e.g.:

var treeMenu = new Ext.ux.TreeMenu({
id: 'tree-panel',
region:'center',
autoScroll: true,
items:[{
text: 'Menu Item',
iconCls: 'rss-icon',
description: 'this is the descripion',
scope: this,
handler: function() { }
},{
text: 'Menu Item',
items:[{
text: 'Child Item'
}]
}]
});

Nodes can be found using hierarchy e.g:


treeMenu.getNodeByHierarchy([0]);

Will return the first item in the treemenu.

getNodeByHierarchy( Array hierarchy ) : Node
Gets a node in this tree by its hierarchy map
Parameters:

* hierarchy : Array

Returns:

* Node

A nodes hierarchy can be found using getNodeHierarchy e.g:


treeMenu.getNodeHierarchy(node);

Will return the hierarchy array.

getNodeHierarchy( Node node ) : Node
Returns the passed node's hierarchy.
Parameters:

* node : Node

Returns:

* hierarchy Array

Menu items can be added later using the TreeMenu's add function e.g:


treeMenu.add({
text: 'Additional Menu item',
description: 'this is added after instantiation.',
items: [{
text: 'Additional Menu Child item',
}]
});

add(menunode / menunode config) : Node

Creates a node and adds it to the treemenu.
Menunodes passed with appendTo config will be appended at that point in the treemenu.

eg:
treeMenu.add({
text: 'Menu item',
description: 'this is added after instantiation, using an array hierarchy to specify destination.',
appendTo: [1]
});

var parentNode = treeMenu.getNodeByHierarchy([1]);
treeMenu.add({
text: 'Menu item',
description: 'this is added after instantiation, using the desired parentnode to specify destination.',
appendTo: parentNode
});

Parameters:

* node config : Object / Node
The node to create and add to the treemenu.

Returns:

* Node
The added node


Or inserted into a position using the insert function:


treeMenu.insert({
text: 'Inserted Item',
description: 'this item is inserted using position and array hierarchy'
},0,[1]);


insert(menunode / menunode config, int item position, [hierarchy map array to new parentnode]) : Node

If passed menunode config it will create the node.

Inserts the node into the position desired.

Parameters:

* node config / node : Object / Node
The node to [create and] insert
* item position : int
The position to insert the node at
* item's new parent hierarchy : Array
(optional) The hierarchal position of the desired parent

Returns:

* Node
The inserted node

Nodes can be removed with the remove function:


treeMenu.remove([1,0]); or:


var node = treeMenu.getNodeById('seconditem');
treeMenu.remove(node);

remove(node hierarchy / node) : Node

Removes node passed or node at passed hierarchy.

Parameters:

* node / node hierarchy : Node / Array
The node or node hierarchy map to remove.

Returns:

* null

MenuNodes

MenuNodes are (mostly) identical to normal treenodes. However there are a couple property differences:

appendTo: (this is explained above in 'add')

iconSize: 'small' / 'normal' / 'large' -- defaults to 'normal'


This defines the nodes icon size which are as follows:
small: 16px * 16px
normal: 32px * 32px
large: 64px * 64px

handler: Fn
A function called when the menunode is clicked.
scope: Object
The scope of the handler.

galdaka
15 Dec 2008, 11:48 PM
Hi,

Sorry for my English,

Escellent work!!

Live example: http://www.jadacosta.es/extjs/examples/treemenu/index.html

Various suggestions:

1) Not work in IE!. OK in FF2.
2) Use the Ext base css and images. Give the option to change by css. With this way you will can standarize your component for all future Ext themes.


Greetings,

NeonMonk
16 Dec 2008, 12:11 AM
Thanks :)

I would have used the Ext base images.. however they're only 16x16! My thinking for the treemenu is for nice large icons and menus. So I was aiming for a norm of 32x32.

I'm using the Simplicio icon set (http://www.smashingmagazine.com/2008/09/02/simplicio-a-free-icon-set/) which are free for all uses. But my intentions were for people to use their own icons. In fact, I would have (if I had the time) designed my own because I didn't really want to keep to the folder/file metaphor.

All icons can easily be changed in treemenu.css. Just look for:
folder-open.gif
folder-open-large.gif
folder-open-small.gif
folder-closed.gif
folder-closed-large.gif
folder-closed-small.gif
file.gif
file-small.gif
file-large.gif

NeonMonk
16 Dec 2008, 12:22 AM
OK, I just did a quick test in ie6. TreeMenu works. Resizing the js source window doesn't thanks to a bug in ext-all.

But otherwise it seems to work. Unfortunately it does need the fix (otherwise it errors in mouseout of the menunodes):


Ext.lib.Event.getRelatedTarget = function(M) {
M = M.browserEvent || M;
var L = M.relatedTarget;
if (!L) {
if (Ext.isIE) { return false; }
if (M.type == "mouseout") {
L = M.toElement
} else {
if (M.type == "mouseover") {
L = M.fromElement
}
}
}
return this.resolveTextNode(L)
};

Don't ask me why, see: http://extjs.com/forum/showthread.php?t=55208