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/*
65     Returns the <li> instance that is the parent node of the  
66     target of a "contextmenu" event.
67*/ 
68 
69function getListItemFromEventTarget(p_oNode) { 
70 
71    if (p_oNode.tagName.toUpperCase() == "LI") { 
72     
73        return p_oNode; 
74 
75    } 
76    else { 
77 
78 
79        /*
80             If the target of the event was a child of an <li>, 
81             get the parent <li> element.
82        */ 
83 
84        do { 
85 
86            if (p_oNode.tagName.toUpperCase() == "LI") { 
87 
88                return p_oNode;                             
89             
90            } 
91 
92        } 
93        while ((p_oNode = p_oNode.parentNode)); 
94     
95    } 
96 
97
98 
99 
100// "click" event handler for each item in the ewe context menu 
101 
102function onEweContextMenuClick(p_sType, p_aArgs) { 
103 
104    /*
105         The second item in the arguments array (p_aArgs) 
106         passed back to the "click" event handler is the 
107         MenuItem instance that was the target of the 
108         "click" event.
109    */ 
110 
111    var oItem = p_aArgs[1], // The MenuItem that was clicked 
112        oLI; 
113 
114 
115    if (oItem) { 
116 
117        oLI = getListItemFromEventTarget(this.contextEventTarget); 
118 
119 
120        switch (oItem.index) { 
121         
122            case 0:     // Edit name 
123 
124                editEweName(oLI); 
125             
126            break
127 
128 
129            case 1:     // Clone 
130 
131                cloneEwe(oLI, this); 
132 
133            break
134             
135 
136            case 2:     // Delete 
137 
138                deleteEwe(oLI); 
139 
140            break;                     
141         
142        } 
143     
144    } 
145 
146
147 
148// "render" event handler for the ewe context menu 
149 
150function onContextMenuRender(p_sType, p_aArgs) { 
151 
152    //  Add a "click" event handler to the ewe context menu 
153 
154    this.subscribe("click", onEweContextMenuClick); 
155 
156
157 
158 
159// Add a "render" event handler to the ewe context menu 
160 
161oEweContextMenu.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 | ?

Menu Family Examples:

More Menu Family Resources:

Copyright © 2008 Yahoo! Inc. All rights reserved.

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