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 "beforeShow" 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 | 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 | |
68 | var oSelectedTR; // The currently selected TR |
69 | |
70 | |
71 | /* |
72 | "beforeshow" event handler for the ContextMenu instance - |
73 | replaces the content of the ContextMenu instance based |
74 | on the CSS class name of the <tr> element that triggered |
75 | its display. |
76 | */ |
77 | |
78 | function onContextMenuBeforeShow(p_sType, p_aArgs) { |
79 | |
80 | var oTarget = this.contextEventTarget, |
81 | aMenuItems, |
82 | aClasses; |
83 | |
84 | |
85 | if (this.getRoot() == this) { |
86 | |
87 | /* |
88 | Get the <tr> that was the target of the |
89 | "contextmenu" event. |
90 | */ |
91 | |
92 | oSelectedTR = oTarget.nodeName.toUpperCase() == "TR" ? |
93 | oTarget : Dom.getAncestorByTagName(oTarget, "TR"); |
94 | |
95 | |
96 | /* |
97 | Get the array of MenuItems for the CSS class name from |
98 | the "oContextMenuItems" map. |
99 | */ |
100 | |
101 | if (Dom.hasClass(oSelectedTR, "odd")) { |
102 | |
103 | aClasses = oSelectedTR.className.split(" "); |
104 | |
105 | aMenuItems = oContextMenuItems[aClasses[0]]; |
106 | |
107 | } |
108 | else { |
109 | |
110 | aMenuItems = oContextMenuItems[YAHOO.lang.trim(oSelectedTR.className)]; |
111 | |
112 | } |
113 | |
114 | |
115 | // Remove the existing content from the ContentMenu instance |
116 | |
117 | this.clearContent(); |
118 | |
119 | |
120 | // Add the new set of items to the ContentMenu instance |
121 | |
122 | this.addItems(aMenuItems); |
123 | |
124 | |
125 | // Render the ContextMenu instance with the new content |
126 | |
127 | this.render(); |
128 | |
129 | |
130 | /* |
131 | Highlight the <tr> element in the table that was |
132 | the target of the "contextmenu" event. |
133 | */ |
134 | |
135 | Dom.addClass(oSelectedTR, "selected"); |
136 | |
137 | } |
138 | |
139 | } |
140 | |
141 | |
142 | /* |
143 | "hide" event handler for the ContextMenu - used to |
144 | clear the selected <tr> element in the table. |
145 | */ |
146 | |
147 | function onContextMenuHide(p_sType, p_aArgs) { |
148 | |
149 | if (this.getRoot() == this && oSelectedTR) { |
150 | |
151 | Dom.removeClass(oSelectedTR, "selected"); |
152 | |
153 | } |
154 | |
155 | } |
156 | |
157 | |
158 | /* |
159 | Instantiate a ContextMenu: The first argument passed to |
160 | the constructor is the id of the element to be created; the |
161 | second is an object literal of configuration properties. |
162 | */ |
163 | |
164 | var oContextMenu = new YAHOO.widget.ContextMenu("contextmenu", { |
165 | trigger: "dataset", |
166 | lazyload: true |
167 | }); |
168 | |
169 | |
170 | /* |
171 | Subscribe to the ContextMenu instance's "beforeshow" and |
172 | "hide" events. |
173 | */ |
174 | |
175 | oContextMenu.subscribe("beforeShow", onContextMenuBeforeShow); |
176 | oContextMenu.subscribe("hide", onContextMenuHide); |
177 | |
178 | }); |
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 © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Copyright Policy - Job Openings