|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- (function ($) {
- // register namespace
- $.extend(true, window, {
- "Slick": {
- "Plugins": {
- "HeaderMenu": HeaderMenu
- }
- }
- });
-
-
- /***
- * A plugin to add drop-down menus to column headers.
- *
- * USAGE:
- *
- * Add the plugin .js & .css files and register it with the grid.
- *
- * To specify a menu in a column header, extend the column definition like so:
- *
- * var columns = [
- * {
- * id: 'myColumn',
- * name: 'My column',
- *
- * // This is the relevant part
- * header: {
- * menu: {
- * items: [
- * {
- * // menu item options
- * },
- * {
- * // menu item options
- * }
- * ]
- * }
- * }
- * }
- * ];
- *
- *
- * Available menu options:
- * tooltip: Menu button tooltip.
- *
- *
- * Available menu item options:
- * title: Menu item text.
- * disabled: Whether the item is disabled.
- * tooltip: Item tooltip.
- * command: A command identifier to be passed to the onCommand event handlers.
- * iconCssClass: A CSS class to be added to the menu item icon.
- * iconImage: A url to the icon image.
- *
- *
- * The plugin exposes the following events:
- * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.
- * Event args:
- * grid: Reference to the grid.
- * column: Column definition.
- * menu: Menu options. Note that you can change the menu items here.
- *
- * onCommand: Fired on menu item click for buttons with 'command' specified.
- * Event args:
- * grid: Reference to the grid.
- * column: Column definition.
- * command: Button command identified.
- * button: Button options. Note that you can change the button options in your
- * event handler, and the column header will be automatically updated to
- * reflect them. This is useful if you want to implement something like a
- * toggle button.
- *
- *
- * @param options {Object} Options:
- * buttonCssClass: an extra CSS class to add to the menu button
- * buttonImage: a url to the menu button image (default '../images/down.gif')
- * @class Slick.Plugins.HeaderButtons
- * @constructor
- */
- function HeaderMenu(options) {
- var _grid;
- var _self = this;
- var _handler = new Slick.EventHandler();
- var _defaults = {
- buttonCssClass: null,
- buttonImage: "../images/down.gif"
- };
- var $menu;
- var $activeHeaderColumn;
-
-
- function init(grid) {
- options = $.extend(true, {}, _defaults, options);
- _grid = grid;
- _handler
- .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)
- .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);
-
- // Force the grid to re-render the header now that the events are hooked up.
- _grid.setColumns(_grid.getColumns());
-
- // Hide the menu on outside click.
- $(document.body).bind("mousedown", handleBodyMouseDown);
- }
-
-
- function destroy() {
- _handler.unsubscribeAll();
- $(document.body).unbind("mousedown", handleBodyMouseDown);
- }
-
-
- function handleBodyMouseDown(e) {
- if ($menu && $menu[0] != e.target && !$.contains($menu[0], e.target)) {
- hideMenu();
- }
- }
-
-
- function hideMenu() {
- if ($menu) {
- $menu.remove();
- $menu = null;
- $activeHeaderColumn
- .removeClass("slick-header-column-active");
- }
- }
-
- function handleHeaderCellRendered(e, args) {
- var column = args.column;
- var menu = column.header && column.header.menu;
-
- if (menu) {
- var $el = $("<div></div>")
- .addClass("slick-header-menubutton")
- .data("column", column)
- .data("menu", menu);
-
- if (options.buttonCssClass) {
- $el.addClass(options.buttonCssClass);
- }
-
- if (options.buttonImage) {
- $el.css("background-image", "url(" + options.buttonImage + ")");
- }
-
- if (menu.tooltip) {
- $el.attr("title", menu.tooltip);
- }
-
- $el
- .bind("click", showMenu)
- .appendTo(args.node);
- }
- }
-
-
- function handleBeforeHeaderCellDestroy(e, args) {
- var column = args.column;
-
- if (column.header && column.header.menu) {
- $(args.node).find(".slick-header-menubutton").remove();
- }
- }
-
-
- function showMenu(e) {
- var $menuButton = $(this);
- var menu = $menuButton.data("menu");
- var columnDef = $menuButton.data("column");
-
- // Let the user modify the menu or cancel altogether,
- // or provide alternative menu implementation.
- if (_self.onBeforeMenuShow.notify({
- "grid": _grid,
- "column": columnDef,
- "menu": menu
- }, e, _self) == false) {
- return;
- }
-
-
- if (!$menu) {
- $menu = $("<div class='slick-header-menu'></div>")
- .appendTo(document.body);
- }
- $menu.empty();
-
-
- // Construct the menu items.
- for (var i = 0; i < menu.items.length; i++) {
- var item = menu.items[i];
-
- var $li = $("<div class='slick-header-menuitem'></div>")
- .data("command", item.command || '')
- .data("column", columnDef)
- .data("item", item)
- .bind("click", handleMenuItemClick)
- .appendTo($menu);
-
- if (item.disabled) {
- $li.addClass("slick-header-menuitem-disabled");
- }
-
- if (item.tooltip) {
- $li.attr("title", item.tooltip);
- }
-
- var $icon = $("<div class='slick-header-menuicon'></div>")
- .appendTo($li);
-
- if (item.iconCssClass) {
- $icon.addClass(item.iconCssClass);
- }
-
- if (item.iconImage) {
- $icon.css("background-image", "url(" + item.iconImage + ")");
- }
-
- $("<span class='slick-header-menucontent'></span>")
- .text(item.title)
- .appendTo($li);
- }
-
-
- // Position the menu.
- $menu
- .css("top", $(this).offset().top + $(this).height())
- .css("left", $(this).offset().left);
-
-
- // Mark the header as active to keep the highlighting.
- $activeHeaderColumn = $menuButton.closest(".slick-header-column");
- $activeHeaderColumn
- .addClass("slick-header-column-active");
- }
-
-
- function handleMenuItemClick(e) {
- var command = $(this).data("command");
- var columnDef = $(this).data("column");
- var item = $(this).data("item");
-
- if (item.disabled) {
- return;
- }
-
- hideMenu();
-
- if (command != null && command != '') {
- _self.onCommand.notify({
- "grid": _grid,
- "column": columnDef,
- "command": command,
- "item": item
- }, e, _self);
- }
-
- // Stop propagation so that it doesn't register as a header click event.
- e.preventDefault();
- e.stopPropagation();
- }
-
- $.extend(this, {
- "init": init,
- "destroy": destroy,
-
- "onBeforeMenuShow": new Slick.Event(),
- "onCommand": new Slick.Event()
- });
- }
- })(jQuery);
|