This example creates context menu for an HTML table and illustrates how the content of a ContextMenu instance can be replaced on the fly based on the element that triggered its display.
Please Note: Opera users will need to do the following to use this example:
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 each 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 an <table>
and giving
<tr>
elements that should have the same context menu a
similar class name.
Next, use the onContentReady
method of the Event utility to listen for when the <table>
element is are ready to be scripted.
1 | YAHOO.util.Event.onContentReady("dataset", function () { |
2 | |
3 | |
4 | }); |
view plain | print | ? |
Inside the function passed to the Event Utility's onContentReady
method, create a
shortcut to the Dom Utility (since it will be used frequently) and an object literal that maps each
class name to a set of MenuItem configuration properties.
1 | YAHOO.util.Event.onContentReady("dataset", function () { |
2 | |
3 | var Dom = YAHOO.util.Dom; |
4 | |
5 | /* |
6 | Map of CSS class names to arrays of MenuItem |
7 | configuration properties. |
8 | */ |
9 | |
10 | var oContextMenuItems = { |
11 | |
12 | "type1": [ |
13 | "Context Menu 1, Item 1", |
14 | { |
15 | text: "Context Menu 1, Item 2", |
16 | submenu: { |
17 | id: "submenu1", |
18 | lazyload: true, |
19 | itemdata: [ |
20 | "Context Menu 1 Submenu, Item 1", |
21 | "Context Menu 1 Submenu, Item 2", |
22 | "Context Menu 1 Submenu, Item 3", |
23 | "Context Menu 1 Submenu, Item 4" |
24 | ] |
25 | } |
26 | }, |
27 | "Context Menu 1, Item 3", |
28 | "Context Menu 1, Item 4" |
29 | ], |
30 | |
31 | "type2": [ |
32 | "Context Menu 2, Item 1", |
33 | "Context Menu 2, Item 2", |
34 | "Context Menu 2, Item 3", |
35 | "Context Menu 2, Item 4", |
36 | "Context Menu 2, Item 5", |
37 | "Context Menu 2, Item 6", |
38 | "Context Menu 2, Item 7", |
39 | "Context Menu 2, Item 8", |
40 | "Context Menu 2, Item 9", |
41 | "Context Menu 2, Item 10" |
42 | ], |
43 | |
44 | "type3": [ |
45 | "Context Menu 3, Item 1", |
46 | "Context Menu 3, Item 2", |
47 | "Context Menu 3, Item 3", |
48 | "Context Menu 3, Item 4" |
49 | ], |
50 | |
51 | "type4": [ |
52 | "Context Menu 4, Item 1", |
53 | "Context Menu 4, Item 2" |
54 | ], |
55 | |
56 | "type5": [ |
57 | "Context Menu 5, Item 1", |
58 | "Context Menu 5, Item 2", |
59 | "Context Menu 5, Item 3", |
60 | "Context Menu 5, Item 4", |
61 | "Context Menu 5, Item 5", |
62 | "Context Menu 5, Item 6" |
63 | ] |
64 | |
65 | }; |
66 | |
67 | }); |
view plain | print | ? |
Lastly, add a "triggerContextMenu" event handler to the ContextMenu instance.
This event handler makes use of the "contextEventTarget" property to determine
which <tr>
element was the target of the "contextmenu"
event. Once found, the <tr>
element's class name is
used to look up its corresponding menu items in the "oContextMenuItems"
map, which are then added to the ContextMenu instance via the "addItems" method.
1 | /* |
2 | Initialize the ContextMenu instance when the the elements |
3 | that trigger their display are ready to be scripted. |
4 | */ |
5 | |
6 | YAHOO.util.Event.onContentReady("dataset", function () { |
7 | |
8 | var Dom = YAHOO.util.Dom; |
9 | |
10 | /* |
11 | Map of CSS class names to arrays of MenuItem |
12 | configuration properties. |
13 | */ |
14 | |
15 | var oContextMenuItems = { |
16 | |
17 | "type1": [ |
18 | "Context Menu 1, Item 1", |
19 | { |
20 | text: "Context Menu 1, Item 2", |
21 | submenu: { |
22 | id: "submenu1", |
23 | lazyload: true, |
24 | itemdata: [ |
25 | "Context Menu 1 Submenu, Item 1", |
26 | "Context Menu 1 Submenu, Item 2", |
27 | "Context Menu 1 Submenu, Item 3", |
28 | "Context Menu 1 Submenu, Item 4" |
29 | ] |
30 | } |
31 | }, |
32 | "Context Menu 1, Item 3", |
33 | "Context Menu 1, Item 4" |
34 | ], |
35 | |
36 | "type2": [ |
37 | "Context Menu 2, Item 1", |
38 | "Context Menu 2, Item 2", |
39 | "Context Menu 2, Item 3", |
40 | "Context Menu 2, Item 4", |
41 | "Context Menu 2, Item 5", |
42 | "Context Menu 2, Item 6", |
43 | "Context Menu 2, Item 7", |
44 | "Context Menu 2, Item 8", |
45 | "Context Menu 2, Item 9", |
46 | "Context Menu 2, Item 10" |
47 | ], |
48 | |
49 | "type3": [ |
50 | "Context Menu 3, Item 1", |
51 | "Context Menu 3, Item 2", |
52 | "Context Menu 3, Item 3", |
53 | "Context Menu 3, Item 4" |
54 | ], |
55 | |
56 | "type4": [ |
57 | "Context Menu 4, Item 1", |
58 | "Context Menu 4, Item 2" |
59 | ], |
60 | |
61 | "type5": [ |
62 | "Context Menu 5, Item 1", |
63 | "Context Menu 5, Item 2", |
64 | "Context Menu 5, Item 3", |
65 | "Context Menu 5, Item 4", |
66 | "Context Menu 5, Item 5", |
67 | "Context Menu 5, Item 6" |
68 | ] |
69 | |
70 | }; |
71 | |
72 | var oSelectedTR, // The currently selected TR |
73 | rendered; // Whether or not the menu has been rendered |
74 | |
75 | /* |
76 | "triggerContextMenu" event handler for the ContextMenu instance - |
77 | replaces the content of the ContextMenu instance based |
78 | on the CSS class name of the <tr> element that triggered |
79 | its display. |
80 | */ |
81 | |
82 | function onTriggerContextMenu(p_sType, p_aArgs) { |
83 | |
84 | var oTarget = this.contextEventTarget, |
85 | aMenuItems, |
86 | aClasses; |
87 | |
88 | |
89 | if (this.getRoot() == this) { |
90 | |
91 | /* |
92 | Get the <tr> that was the target of the |
93 | "contextmenu" event. |
94 | */ |
95 | |
96 | oSelectedTR = oTarget.nodeName.toUpperCase() == "TR" ? |
97 | oTarget : Dom.getAncestorByTagName(oTarget, "TR"); |
98 | |
99 | |
100 | /* |
101 | Get the array of MenuItems for the CSS class name from |
102 | the "oContextMenuItems" map. |
103 | */ |
104 | |
105 | if (Dom.hasClass(oSelectedTR, "odd")) { |
106 | aClasses = oSelectedTR.className.split(" "); |
107 | aMenuItems = oContextMenuItems[aClasses[0]]; |
108 | } else { |
109 | aMenuItems = oContextMenuItems[YAHOO.lang.trim(oSelectedTR.className)]; |
110 | } |
111 | |
112 | // Remove the existing content from the ContentMenu instance |
113 | this.clearContent(); |
114 | |
115 | // Add the new set of items to the ContentMenu instance |
116 | this.addItems(aMenuItems); |
117 | |
118 | // Render the ContextMenu instance with the new content |
119 | if (!rendered) { |
120 | this.render(this.cfg.getProperty("container")); |
121 | } else { |
122 | this.render(); |
123 | } |
124 | |
125 | /* |
126 | Highlight the <tr> element in the table that was |
127 | the target of the "contextmenu" event. |
128 | */ |
129 | Dom.addClass(oSelectedTR, "selected"); |
130 | } |
131 | } |
132 | |
133 | /* |
134 | "hide" event handler for the ContextMenu - used to |
135 | clear the selected <tr> element in the table. |
136 | */ |
137 | function onContextMenuHide(p_sType, p_aArgs) { |
138 | if (this.getRoot() == this && oSelectedTR) { |
139 | Dom.removeClass(oSelectedTR, "selected"); |
140 | } |
141 | } |
142 | |
143 | /* |
144 | Instantiate a ContextMenu: The first argument passed to the constructor |
145 | is the id for the Menu element to be created, the second is an |
146 | object literal of configuration properties. |
147 | */ |
148 | |
149 | var oContextMenu = new YAHOO.widget.ContextMenu("contextmenu", { |
150 | trigger: "dataset", |
151 | lazyload: true |
152 | }); |
153 | |
154 | |
155 | /* |
156 | Subscribe to the ContextMenu instance's "triggerContextMenu" event to update content, |
157 | and "hide" event to clear the selected row state. |
158 | */ |
159 | oContextMenu.subscribe("triggerContextMenu", onTriggerContextMenu); |
160 | oContextMenu.subscribe("hide", onContextMenuHide); |
161 | oContextMenu.subscribe("render", function() {rendered = true;}); |
162 | }); |
view plain | print | ? |
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.
Copyright © 2011 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Copyright Policy - Job Openings