YUI Library Home

YUI Library Examples: Menu Family: Context Menu

Menu Family: Context Menu

This example demonstrates how to use the ContextMenu widget to create two context menus. There is one for each ewe that is created and one for the green field that the ewes graze in. Use the ewe context menu to rename, clone or delete Dolly. The field's context menu enables the deletion of all the ewes from the field, the addition of a new ewe and the ability to modify the color of the grass.

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.

Begin by defining an array of text labels, each of which represents an item in the ContextMenu. Next, use the onContentReady method of the Event utility to instantiate the ContextMenu as soon as the elements whose "contextmenu" event trigger its display are ready to be scripted.

1/*
2     Initialize the ContextMenu instances when the the elements 
3     that trigger their display are ready to be scripted.
4*/ 
5 
6YAHOO.util.Event.onContentReady("clones"function () { 
7 
8    /*
9         Array of text labels for the MenuItem instances to be
10         added to the ContextMenu instanc.
11    */ 
12 
13    var aMenuItems = ["Edit Name""Clone""Delete" ];  
14 
15 
16    /*
17         Instantiate a ContextMenu:  The first argument passed to 
18         the constructor is the id of the element to be created; the 
19         second is an object literal of configuration properties.
20    */ 
21 
22    var oEweContextMenu = new YAHOO.widget.ContextMenu( 
23                                "ewecontextmenu",  
24                                { 
25                                    trigger: oClones.childNodes, 
26                                    itemdata: aMenuItems, 
27                                    lazyload: true                                     
28                                }  
29                            ); 
30      
31}); 
view plain | print | ?

This ContextMenu makes use of a couple configuration properties, each of which is set via an object literal passed as the second argument to the constructor. The "trigger" configuration property defines the element(s) whose "contextmenu" event trigger the display of the ContextMenu instance. In this case, each <li> element of the <ul id="clones"> element is a trigger for the ContextMenu. The "lazyload" property is used speed up the initial load time of the ContextMenu instance. By setting the "lazyload" property to "true," the ContextMenu will not be appended to the page until the initial firing of a "contextmenu" event by one of the elements defined as its trigger. Additionally, use of the "lazyload" property defers the initialization and rendering of submenus until just before it is initially made visible. Lastly, the "itemdata" property is set to the array of MenuItem configuration properties; each item in the array will be used to add a new item to the ContextMenu when it is rendered.

When multiple elements are defined as the "trigger" for a ContextMenu instance, the "contextEventTarget" property can be used to determine which element triggered its display. The "contextEventTarget" property returns a reference to the HTML element whose "contextmenu" event triggered the display of the ContextMenu instance. In this example, the "contextEventTarget" property is used inside the scope of a "click" event listener (see "onEweContextMenuClick") to determine which <li> element triggered the display of the "ewe" ContextMenu instance.

1// Maintain a reference to the "clones" <ul> 
2 
3var oClones = this
4 
5 
6// Clone the first ewe so that we can create more later 
7 
8var oLI = oClones.getElementsByTagName("li")[0]; 
9var oEweTemplate = oLI.cloneNode(true); 
10 
11 
12// Renames an "ewe" 
13 
14function editEweName(p_oLI) { 
15 
16    var oCite = p_oLI.lastChild; 
17 
18 
19    if (oCite.nodeType != 1) { 
20     
21        oCite = oCite.previousSibling; 
22 
23    } 
24 
25    var oTextNode = oCite.firstChild; 
26 
27    var sName = window.prompt("Enter a new name for ",  
28                oTextNode.nodeValue); 
29 
30 
31    if (sName && sName.length > 0) { 
32         
33        oTextNode.nodeValue = sName; 
34 
35    } 
36 
37
38 
39 
40// Clones an "ewe" 
41 
42function cloneEwe(p_oLI, p_oMenu) { 
43 
44    var oClone = p_oLI.cloneNode(true); 
45 
46    p_oLI.parentNode.appendChild(oClone); 
47 
48    p_oMenu.cfg.setProperty("trigger", oClones.childNodes); 
49 
50
51 
52 
53// Deletes an "ewe" 
54 
55function deleteEwe(p_oLI) { 
56 
57    var oUL = p_oLI.parentNode; 
58 
59    oUL.removeChild(p_oLI); 
60 
61
62 
63 
64// "click" event handler for each item in the ewe context menu 
65 
66function onEweContextMenuClick(p_sType, p_aArgs) { 
67 
68    /*
69         The second item in the arguments array (p_aArgs) 
70         passed back to the "click" event handler is the 
71         MenuItem instance that was the target of the 
72         "click" event.
73    */ 
74 
75    var oItem = p_aArgs[1], // The MenuItem that was clicked 
76        oTarget = this.contextEventTarget, 
77        oLI; 
78 
79 
80    if (oItem) { 
81 
82        oLI = oTarget.nodeName.toUpperCase() == "LI" ?  
83                oTarget : YAHOO.util.Dom.getAncestorByTagName(oTarget, "LI"); 
84 
85 
86        switch (oItem.index) { 
87         
88            case 0:     // Edit name 
89 
90                editEweName(oLI); 
91             
92            break
93 
94 
95            case 1:     // Clone 
96 
97                cloneEwe(oLI, this); 
98 
99            break
100             
101 
102            case 2:     // Delete 
103 
104                deleteEwe(oLI); 
105 
106            break;                     
107         
108        } 
109     
110    } 
111 
112
113 
114// "render" event handler for the ewe context menu 
115 
116function onContextMenuRender(p_sType, p_aArgs) { 
117 
118    //  Add a "click" event handler to the ewe context menu 
119 
120    this.subscribe("click", onEweContextMenuClick); 
121 
122
123 
124 
125// Add a "render" event handler to the ewe context menu 
126 
127oEweContextMenu.subscribe("render", onContextMenuRender); 
view plain | print | ?

In the example above, a single "click" event handler is added to the ContextMenu instance and discrete functionality is executed depending of the index of the MenuItem instance that was the target of the event. An alternative way of listening for the "click" event on MenuItem instances is to use the "onclick" configuration property. The "onclick" configuration property provides an easy way define a "click " event listener for individual items when building menus from script. The "onclick" configuration property accepts an object literal representing the code to be executed when the MenuItem instance is clicked. The format for the object literal is:

1
2    fn: Function (Required),    // The handler to call when the event fires. 
3    obj: Object (Optional), // An object to pass back to the handler. 
4    scope: Object (Optional)    // The object to use for the scope of the handler. (By default the scope is the YAHOO.widget.MenuItem instance) 
5
view plain | print | ?

The second ContextMenu instance in this example makes use of the "onclick" configuration property:

1// Deletes an ewe from the field 
2 
3function deleteEwes() { 
4 
5    oEweContextMenu.cfg.setProperty("target"null); 
6 
7    oClones.innerHTML = ""
8 
9 
10    function onHide(p_sType, p_aArgs, p_oItem) { 
11 
12        p_oItem.cfg.setProperty("disabled"true); 
13     
14        p_oItem.parent.unsubscribe("hide", onHide, p_oItem); 
15     
16    } 
17 
18    this.parent.subscribe("hide", onHide, this); 
19 
20
21 
22 
23// Creates a new ewe and appends it to the field 
24 
25function createNewEwe() { 
26 
27    var oLI = oEweTemplate.cloneNode(true); 
28     
29    oClones.appendChild(oLI); 
30 
31    this.parent.getItem(1).cfg.setProperty("disabled"false); 
32 
33    oEweContextMenu.cfg.setProperty("trigger", oClones.childNodes); 
34 
35
36 
37 
38// Sets the color of the grass in the field 
39 
40function setFieldColor(p_sType, p_aArgs, p_sColor) { 
41 
42    var oCheckedItem = this.parent.checkedItem; 
43 
44    if (oCheckedItem != this) { 
45 
46        YAHOO.util.Dom.setStyle("clones""backgroundColor", p_sColor); 
47         
48        this.cfg.setProperty("checked"true); 
49 
50 
51        oCheckedItem.cfg.setProperty("checked"false); 
52 
53        this.parent.checkedItem = this
54     
55    } 
56 
57
58 
59 
60// "render" event handler for the field context menu 
61 
62function onFieldMenuRender(p_sType, p_aArgs) { 
63 
64    if (this.parent) {  // submenu 
65 
66        this.checkedItem = this.getItem(0); 
67 
68    } 
69 
70
71 
72 
73/*
74     Array of object literals - each containing configuration 
75     properties for the items for the context menu.
76*/ 
77 
78var oFieldContextMenuItemData = [ 
79 
80    { 
81        text: "Field color",  
82        submenu: {  
83            id: "fieldcolors",  
84            itemdata: [ 
85                { text: "Light Green", onclick: { fn: setFieldColor, obj: "#99cc66", checked: true } },  
86                { text: "Medium Green", onclick: { fn: setFieldColor, obj: "#669933" } },  
87                { text: "Dark Green", onclick: { fn: setFieldColor, obj: "#336600" } } 
88            ]  
89        }  
90    }, 
91    { text: "Delete all", onclick: { fn: deleteEwes } }, 
92    { text: "New Ewe", onclick: { fn: createNewEwe } } 
93 
94]; 
95 
96 
97/*
98     Instantiate a ContextMenu:  The first argument passed to 
99     the constructor is the id of the element to be created; the 
100     second is an object literal of configuration properties.
101*/ 
102 
103var oFieldContextMenu = new YAHOO.widget.ContextMenu( 
104                                "fieldcontextmenu"
105                                { 
106                                    trigger: "clones"
107                                    itemdata: oFieldContextMenuItemData, 
108                                    lazyload: true 
109                                } 
110                            ); 
111 
112 
113// Add a "render" event handler to the field context menu 
114 
115oFieldContextMenu.subscribe("render", onFieldMenuRender); 
view plain | print | ?

Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

Menu Family Examples:

More Menu Family Resources:

Copyright © 2009 Yahoo! Inc. All rights reserved.

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