I have been searching on the internet for a good example about making a TreeView or TreePanel with contextmenu and couldn't find any. I used 0.40 yui-ext and latest yui libraries and after 2 days of struggling finally got something working. Here is the detailed explanation with code.
First I made yuitest.html
Code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title> TreePanel</title>
<script type="text/javascript" src="lib/yahoo/yahoo.js"></script>
<script type="text/javascript" src="lib/event/event.js"></script>
<script type="text/javascript" src="lib/dom/dom.js"></script>
<script type="text/javascript" src="lib/container/container_core.js"></script>
<script type="text/javascript" src="lib/menu/menu.js" ></script>
<script type="text/javascript" src="lib/treeview/treeview.js" ></script>
<script type="text/javascript" src="lib/utilities/utilities.js"></script>
<script type="text/javascript" src="yui-ext-0.40/jscripts/yui-ext.js"></script>
<link rel="stylesheet" type="text/css" href="yui-ext-0.40/css/yui-ext.css" />
<link rel="stylesheet" type="text/css" href="css/menu.css" />
<link rel="stylesheet" type="text/css" href="examples.css" />
<link rel="stylesheet" type="text/css" href="lib/reset/reset.css">
<link rel="stylesheet" type="text/css" href="lib/fonts/fonts.css">
<script type="text/javascript">
// shorthand
var Tree = YAHOO.ext.tree;
var tree;
var root;
function init(){
tree = new Tree.TreePanel('tree-div', {
animate:true,
loader: new Tree.TreeLoader({dataUrl:"http://localhost/test.php",
baseParams: {}
}),
enableDD:true,
containerScroll: true
});
// set the root node
root = new Tree.AsyncTreeNode({
text: 'yui-ext',
draggable:false,
id:'mainportal'
});
tree.setRootNode(root);
// render the tree
tree.render();
root.expand();
};
function assignConmenu() {
if(root.isLoaded()){
var children = root.childNodes;
//alert("test:"+children);
for ( var i=0; i < children.length; i++ ) {
children[i].on("contextmenu", conMenu, children[i], true);
console.log("timesd:"+i);
}
}
};
function conMenu() {
var aMenuItems = [ {text: "Cut"},{text:"Copy"},{text:"Paste"} ];
//if( typeof oContextMenu != "undefined"){alert("contextmenu exist");oContextMenu.destroy;}
if ( typeof oContextMenu != "undefined"){
oContextMenu.destroy();
}
this.select(); //to make the right clicked menu node highlighted..remove if you don't need it.
oContextMenu = new YAHOO.widget.ContextMenu(
"otmenu",
{
trigger: this.ui.elNode.id,
itemdata: aMenuItems,
lazyload: true
}
);
oContextMenu.renderEvent.subscribe(onContextMenuRender, oContextMenu, true);
};
function onContextMenuRender(p_sType,p_aArgs, p_oMenu) {
//alert("inside context menu render");
this.clickEvent.subscribe(onContextMenuClick, this, true);
};
function onContextMenuClick(p_sType,p_aArgs, p_oMenu) {
alert("u have clicked");
};
YAHOO.ext.EventManager.onDocumentReady(init);
YAHOO.ext.EventManager.on(window,"load",assignConmenu, assignConmenu, true);
</script>
</head>
<body>
<div id="tree-div" style="overflow:auto; height:300px;width:250px;border:1px solid #c3daf9;"></div>
</body>
</html>
and test.php has the following contents, put this under apache document root and it will return the JSON object when XHR happens from the TreeLoader.
Code:
[{"text":"yui-ext.js","id":"yui-ext.js","leaf":true,"cls":"file"},{"text":"yui-ext-1125.php","id":"yui-ext-1125.php","leaf":true,"cls":"file"}]
The above example uses all yui-ext and yui libraries. In addition to that i am also copied the menu.css from yui example. Here is the menu.css code.
Code:
/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.txt
Version: 0.12.1
*/
/* Menu styles */
div.yuimenu {
background-color:#f6f7ee;
border:solid 1px #c4c4be;
padding:1px;
}
/* Submenus are positioned absolute and hidden by default */
div.yuimenu div.yuimenu,
div.yuimenubar div.yuimenu {
position:absolute;
visibility:hidden;
}
/* MenuBar Styles */
div.yuimenubar {
background-color:#f6f7ee;
}
/*
Applying a width triggers "haslayout" in IE so that the module's
body clears its floated elements
*/
div.yuimenubar div.bd {
width:100%;
}
/*
Clear the module body for other browsers
*/
div.yuimenubar div.bd:after {
content:'.';
display:block;
clear:both;
visibility:hidden;
height:0;
}
/* Matches the group title (H6) inside a Menu or MenuBar instance */
div.yuimenu h6,
div.yuimenubar h6 {
font-size:100%;
font-weight:normal;
margin:0;
border:solid 1px #c4c4be;
color:#b9b9b9;
}
div.yuimenubar h6 {
float:left;
display:inline; /* Prevent margin doubling in IE */
padding:4px 12px;
border-width:0 1px 0 0;
}
div.yuimenu h6 {
float:none;
display:block;
border-width:1px 0 0 0;
padding:5px 10px 0 10px;
}
/* Matches the UL inside a Menu or MenuBar instance */
div.yuimenubar ul {
list-style-type:none;
margin:0;
padding:0;
}
div.yuimenu ul {
list-style-type:none;
border:solid 1px #c4c4be;
border-width:1px 0 0 0;
margin:0;
padding:10px 0;
}
div.yuimenu ul.first-of-type,
div.yuimenu ul.hastitle,
div.yuimenu h6.first-of-type {
border-width:0;
}
/* MenuItem and MenuBarItem styles */
div.yuimenu li,
div.yuimenubar li {
font-size:85%;
cursor:pointer;
cursor:hand;
white-space:nowrap;
text-align:left;
}
div.yuimenu li.yuimenuitem {
padding:2px 24px;
}
div.yuimenu li li,
div.yuimenubar li li {
font-size:100%;
}
/* Matches the help text for a menu item */
div.yuimenu li em {
font-style:normal;
margin:0 0 0 40px;
}
div.yuimenu li a em {
margin:0;
}
div.yuimenu li a,
div.yuimenubar li a {
/*
"zoom:1" triggers "haslayout" in IE to ensure that the mouseover and
mouseout events bubble to the parent LI in IE.
*/
zoom:1;
color:#000;
text-decoration:none;
}
div.yuimenu li.hassubmenu,
div.yuimenu li.hashelptext {
text-align:right;
}
div.yuimenu li.hassubmenu a.hassubmenu,
div.yuimenu li.hashelptext a.hashelptext {
float:left;
display:inline; /* Prevent margin doubling in IE */
text-align:left;
}
/* Matches focused and selected menu items */
div.yuimenu li.selected,
div.yuimenubar li.selected {
background-color:#8c8ad0;
}
div.yuimenu li.selected a.selected,
div.yuimenubar li.selected a.selected {
text-decoration:underline;
}
div.yuimenu li.selected a.selected,
div.yuimenu li.selected em.selected,
div.yuimenubar li.selected a.selected {
color:#fff;
}
/* Matches disabled menu items */
div.yuimenu li.disabled,
div.yuimenubar li.disabled {
cursor:default;
}
div.yuimenu li.disabled a.disabled,
div.yuimenu li.disabled em.disabled,
div.yuimenubar li.disabled a.disabled {
color:#b9b9b9;
cursor:default;
}
div.yuimenubar li.yuimenubaritem {
float:left;
display:inline; /* Prevent margin doubling in IE */
border-width:0 0 0 1px;
border-style:solid;
border-color:#c4c4be;
padding:4px 24px;
margin:0;
}
div.yuimenubar li.yuimenubaritem.first-of-type {
border-width:0;
}
/* Matches the submenu indicator for menu items */
div.yuimenubar li.yuimenubaritem img {
height:8px;
width:8px;
margin:0 0 0 10px;
vertical-align:middle;
}
div.yuimenu li.yuimenuitem img {
height:8px;
width:8px;
margin:0 -16px 0 0;
padding-left:10px;
border:0;
}
div.yuimenu li.checked {
position:relative;
}
div.yuimenu li.checked img.checked {
height:8px;
width:8px;
margin:0;
padding:0;
border:0;
position:absolute;
left:6px;
_left:-16px; /* Underscore hack b/c this is for IE 6 only */
top:.5em;
}
Run the sample code and post your comments. I do have few questions/bugs from the above example.
1. Context menu appears when I right click the menu node. But it appears even if i right click next to the menu item, ie, the div tag area which holds the menu item. I am not sure how to prevent this. I even noticed the same in yahoo examples.
2. I have to find out a way to customize the context menu per menu item by adding removing the contextmenu items. I think it should be possible.
I followed the alpha documentation for yui-ext 0.40 from
http://www.yui-ext.com/deploy/yui-ext.0.40-alpha/docs/
I forgot to mention that the latest yui-ext-0.40 has a bug in yui-ext.js. The bug is instead of "contextmenu" it has "contentmenu" in two places. Please change it before you run this code otherwise the contextmenu will not appear. (I think this is corrected in svn).
Cee ya,
Thameem[/b][/quote]