Yahoo! Developer Network Home - Help

YDN Site Search

# YUI Library Examples: Menu Family: Adding A Context Menu To A TreeView

# Menu Family: Adding A Context Menu To A TreeView

This example demonstates how to use the ContextMenu widget to add a context menu to a YUI TreeView control. The context menu allows the user to add, edit and remove items from a TreeView instance.

Please Note: Opera users will need to do the following to use this example:

- Opera for Windows: Hold down the control key and click with the left mouse button.
- Opera for OS X: Hold down the command key (⌘) and click with the left mouse button.

View example in new window.

When adding context menus to large data structures like a `<table>` or large list (`<ol>` or `<ul>`), it is recommended to bind a single YAHOO.widget.ContextMenu instance to the structure's root element, than to a set of its child nodes (`<tr>`s or `<li>`s). Doing so significantly improves the performance of a web page or application by reducing the number of "contextmenu" event handlers as well as the number of YAHOO.widget.ContextMenu instances in memory.

Begin by creating a TreeView instance. Next, create an object that maps HTML ids to their corresponding TextNode instances. As each TextNode instance is added to the TreeView, store a reference to it in the map.

/* Initialize the TreeView instance when the "mytreeview" <div> is ready to be scripted. */ YAHOO.util.Event.onAvailable("mytreeview", function () { /* Map of YAHOO.widget.TextNode instances in the TreeView instance. */ var oTextNodeMap = {}; // Creates a TextNode instance and appends it to the TreeView function buildRandomTextBranch(p_oNode) { var oTextNode, i; if (p_oNode.depth < 6) { for (i = 0; i < Math.floor(Math.random() * 4); i++) { oTextNode = new YAHOO.widget.TextNode(p_oNode.label + "-" + i, p_oNode, false); oTextNodeMap[oTextNode.labelElId] = oTextNode; buildRandomTextBranch(oTextNode); } } } // Create a TreeView instance var oTreeView = new YAHOO.widget.TreeView("mytreeview"); var n, oTextNode; for (n = 0; n < Math.floor((Math.random()*4) + 3); n++) { oTextNode = new YAHOO.widget.TextNode("label-" + n, oTreeView.getRoot(), false); /* Add the TextNode instance to the map, using its HTML id as the key. */ oTextNodeMap[oTextNode.labelElId] = oTextNode; buildRandomTextBranch(oTextNode); } oTreeView.draw(); });

Once the TreeView is created, instantiate a ContextMenu specifying the TreeView instance's root element as its trigger. Lastly, add a "triggerContextMenu" event handler for the ContextMenu instance that uses the "contextEventTarget" property to retrieve the TextNode instance that triggered its display. A reference to the TextNode is stored in a variable (`oCurrentTextNode`), so that it can be manipulated by the `addNode`, `editNodeLabel`, and `deleteNode` functions.

/* The YAHOO.widget.TextNode instance whose "contextmenu" DOM event triggered the display of the ContextMenu instance. */ var oCurrentTextNode = null; /* Adds a new TextNode as a child of the TextNode instance that was the target of the "contextmenu" event that triggered the display of the ContextMenu instance. */ function addNode() { var sLabel = window.prompt("Enter a label for the new node: ", ""), oChildNode; if (sLabel && sLabel.length > 0) { oChildNode = new YAHOO.widget.TextNode(sLabel, oCurrentTextNode, false); oCurrentTextNode.refresh(); oCurrentTextNode.expand(); oTextNodeMap[oChildNode.labelElId] = oChildNode; } } /* Edits the label of the TextNode that was the target of the "contextmenu" event that triggered the display of the ContextMenu instance. */ function editNodeLabel() { var sLabel = window.prompt("Enter a new label for this node: ", oCurrentTextNode.getLabelEl().innerHTML); if (sLabel && sLabel.length > 0) { oCurrentTextNode.getLabelEl().innerHTML = sLabel; } } /* Deletes the TextNode that was the target of the "contextmenu" event that triggered the display of the ContextMenu instance. */ function deleteNode() { delete oTextNodeMap[oCurrentTextNode.labelElId]; oTreeView.removeNode(oCurrentTextNode); oTreeView.draw(); } /* "contextmenu" event handler for the element(s) that triggered the display of the ContextMenu instance - used to set a reference to the TextNode instance that triggered the display of the ContextMenu instance. */ function onTriggerContextMenu(p_oEvent) { /* Returns a TextNode instance that corresponds to the DOM element whose "contextmenu" event triggered the display of the ContextMenu instance. */ function getTextNodeFromEventTarget(p_oTarget) { if (p_oTarget.tagName.toUpperCase() == "A" && p_oTarget.className == "ygtvlabel") { return oTextNodeMap[p_oTarget.id]; } else { if (p_oTarget.parentNode && p_oTarget.parentNode.nodeType == 1) { return getTextNodeFromEventTarget(p_oTarget.parentNode); } } } /* Get the TextNode instance that that triggered the display of the ContextMenu instance. */ var oTextNode = getTextNodeFromEventTarget(this.contextEventTarget); if (oTextNode) { oCurrentTextNode = oTextNode; } else { // Cancel the display of the ContextMenu instance. this.cancel(); } } /* Instantiate a ContextMenu: The first argument passed to the constructor is the id of the element to be created; the second is an object literal of configuration properties. */ var oContextMenu = new YAHOO.widget.ContextMenu("mytreecontextmenu", { trigger: "mytreeview", lazyload: true, itemdata: [ { text: "Add Child Node", onclick: { fn: addNode } }, { text: "Edit Node Label", onclick: { fn: editNodeLabel } }, { text: "Delete Node", onclick: { fn: deleteNode } } ] }); /* Subscribe to the "contextmenu" event for the element(s) specified as the "trigger" for the ContextMenu instance. */ oContextMenu.subscribe("triggerContextMenu", onTriggerContextMenu);

### Menu Family Examples:

- Basic Menu From Markup
- Basic Menu From JavaScript
- Grouped Menu Items Using Markup
- Grouped Menu Items Using JavaScript
- Grouped Menu Items With Titles From Markup
- Grouped Menu Items With Titles From JavaScript
- Multi-tiered Menu From Markup
- Multi-tiered Menu From JavaScript
- Handling Menu Click Events
- Listening For Menu Events
- MenuItem Configuration Properties
- Setting Menu Configuration Properties At Runtime
- Website Left Nav With Submenus Built From Markup
- Website Left Nav With Submenus From JavaScript
- Website Top Nav With Submenus Built From Markup
- Website Top Nav With Submenus From JavaScript
- Website Left Nav Using Animation With Submenus Built From Markup
- Website Left Nav Using Animation With Submenus From JavaScript
- Website Top Nav Using Animation With Submenus Built From Markup
- Website Top Nav Using Animation With Submenus From JavaScript
- Context Menu
- Adding A Context Menu To A Table
- Adding A Context Menu To A TreeView
- OS-Style Programs Menu
- Application Menubar
- Implementing ARIA Roles and States with Menu
- Context Menu Integration (included with examples for DataTable Control (beta))
- Menu Buttons (included with examples for Button Control)
- Split Buttons (included with examples for Button Control)
- Color Picker Button (included with examples for Button Control)
- Fixed Width Menu Button (included with examples for Button Control)
- Slider Button (included with examples for Button Control)
- Using the ProfilerViewer API while Profiling the YUI Menu Control (included with examples for ProfilerViewer Control (beta))

### More Menu Family Resources:

- User's Guide (external)
- API Documentation
- Cheat Sheet PDF (external)

Copyright © 2008 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings