3 $.extend(true, window, {
6 "HeaderMenu": HeaderMenu
13 * A plugin to add drop-down menus to column headers.
17 * Add the plugin .js & .css files and register it with the grid.
19 * To specify a menu in a column header, extend the column definition like so:
26 * // This is the relevant part
31 * // menu item options
34 * // menu item options
43 * Available menu options:
44 * tooltip: Menu button tooltip.
47 * Available menu item options:
48 * title: Menu item text.
49 * disabled: Whether the item is disabled.
50 * tooltip: Item tooltip.
51 * command: A command identifier to be passed to the onCommand event handlers.
52 * iconCssClass: A CSS class to be added to the menu item icon.
53 * iconImage: A url to the icon image.
56 * The plugin exposes the following events:
57 * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.
59 * grid: Reference to the grid.
60 * column: Column definition.
61 * menu: Menu options. Note that you can change the menu items here.
63 * onCommand: Fired on menu item click for buttons with 'command' specified.
65 * grid: Reference to the grid.
66 * column: Column definition.
67 * command: Button command identified.
68 * button: Button options. Note that you can change the button options in your
69 * event handler, and the column header will be automatically updated to
70 * reflect them. This is useful if you want to implement something like a
74 * @param options {Object} Options:
75 * buttonCssClass: an extra CSS class to add to the menu button
76 * buttonImage: a url to the menu button image (default '../images/down.gif')
77 * @class Slick.Plugins.HeaderButtons
80 function HeaderMenu(options) {
83 var _handler = new Slick.EventHandler();
89 var $activeHeaderColumn;
93 options = $.extend(true, {}, _defaults, options);
96 .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)
97 .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);
99 // Force the grid to re-render the header now that the events are hooked up.
100 _grid.setColumns(_grid.getColumns());
102 // Hide the menu on outside click.
103 $(document.body).bind("mousedown", handleBodyMouseDown);
108 _handler.unsubscribeAll();
109 $(document.body).unbind("mousedown", handleBodyMouseDown);
113 function handleBodyMouseDown(e) {
114 if ($menu && $menu[0] != e.target && !$.contains($menu[0], e.target)) {
120 function hideMenu() {
125 .removeClass("slick-header-column-active");
129 function handleHeaderCellRendered(e, args) {
130 var column = args.column;
131 var menu = column.header && column.header.menu;
134 var $el = $("<div></div>")
135 .addClass("slick-header-menubutton")
136 .data("column", column)
139 if (options.buttonCssClass) {
140 $el.addClass(options.buttonCssClass);
143 if (options.buttonImage) {
144 $el.css("background-image", "url(" + options.buttonImage + ")");
148 $el.attr("title", menu.tooltip);
152 .bind("click", showMenu)
153 .appendTo(args.node);
158 function handleBeforeHeaderCellDestroy(e, args) {
159 var column = args.column;
161 if (column.header && column.header.menu) {
162 $(args.node).find(".slick-header-menubutton").remove();
167 function showMenu(e) {
168 var $menuButton = $(this);
169 var menu = $menuButton.data("menu");
170 var columnDef = $menuButton.data("column");
172 // Let the user modify the menu or cancel altogether,
173 // or provide alternative menu implementation.
174 if (_self.onBeforeMenuShow.notify({
178 }, e, _self) == false) {
184 $menu = $("<div class='slick-header-menu'></div>")
185 .appendTo(_grid.getContainerNode());
190 // Construct the menu items.
191 for (var i = 0; i < menu.items.length; i++) {
192 var item = menu.items[i];
194 var $li = $("<div class='slick-header-menuitem'></div>")
195 .data("command", item.command || '')
196 .data("column", columnDef)
198 .bind("click", handleMenuItemClick)
202 $li.addClass("slick-header-menuitem-disabled");
206 $li.attr("title", item.tooltip);
209 var $icon = $("<div class='slick-header-menuicon'></div>")
212 if (item.iconCssClass) {
213 $icon.addClass(item.iconCssClass);
216 if (item.iconImage) {
217 $icon.css("background-image", "url(" + item.iconImage + ")");
220 $("<span class='slick-header-menucontent'></span>")
226 // Position the menu.
228 .offset({ top: $(this).offset().top + $(this).height(), left: $(this).offset().left });
231 // Mark the header as active to keep the highlighting.
232 $activeHeaderColumn = $menuButton.closest(".slick-header-column");
234 .addClass("slick-header-column-active");
236 // Stop propagation so that it doesn't register as a header click event.
242 function handleMenuItemClick(e) {
243 var command = $(this).data("command");
244 var columnDef = $(this).data("column");
245 var item = $(this).data("item");
253 if (command != null && command != '') {
254 _self.onCommand.notify({
262 // Stop propagation so that it doesn't register as a header click event.
271 "onBeforeMenuShow": new Slick.Event(),
272 "onCommand": new Slick.Event()