YUI Library Home

YUI Library Examples: Menu Family: Adding A Context Menu To A Table

Menu Family: Adding A Context Menu To A Table

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:

  • 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.

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.

1YAHOO.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.

1YAHOO.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 
6YAHOO.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 | ?

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 © 2011 Yahoo! Inc. All rights reserved.

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