slickgrid added to third-party
[myslice.git] / third-party / slickgrid-2.1 / plugins / slick.headerbuttons.js
1 (function ($) {
2   // register namespace
3   $.extend(true, window, {
4     "Slick": {
5       "Plugins": {
6         "HeaderButtons": HeaderButtons
7       }
8     }
9   });
10
11
12   /***
13    * A plugin to add custom buttons to column headers.
14    *
15    * USAGE:
16    *
17    * Add the plugin .js & .css files and register it with the grid.
18    *
19    * To specify a custom button in a column header, extend the column definition like so:
20    *
21    *   var columns = [
22    *     {
23    *       id: 'myColumn',
24    *       name: 'My column',
25    *
26    *       // This is the relevant part
27    *       header: {
28    *          buttons: [
29    *              {
30    *                // button options
31    *              },
32    *              {
33    *                // button options
34    *              }
35    *          ]
36    *       }
37    *     }
38    *   ];
39    *
40    * Available button options:
41    *    cssClass:     CSS class to add to the button.
42    *    image:        Relative button image path.
43    *    tooltip:      Button tooltip.
44    *    showOnHover:  Only show the button on hover.
45    *    handler:      Button click handler.
46    *    command:      A command identifier to be passed to the onCommand event handlers.
47    *
48    * The plugin exposes the following events:
49    *    onCommand:    Fired on button click for buttons with 'command' specified.
50    *        Event args:
51    *            grid:     Reference to the grid.
52    *            column:   Column definition.
53    *            command:  Button command identified.
54    *            button:   Button options.  Note that you can change the button options in your
55    *                      event handler, and the column header will be automatically updated to
56    *                      reflect them.  This is useful if you want to implement something like a
57    *                      toggle button.
58    *
59    *
60    * @param options {Object} Options:
61    *    buttonCssClass:   a CSS class to use for buttons (default 'slick-header-button')
62    * @class Slick.Plugins.HeaderButtons
63    * @constructor
64    */
65   function HeaderButtons(options) {
66     var _grid;
67     var _self = this;
68     var _handler = new Slick.EventHandler();
69     var _defaults = {
70       buttonCssClass: "slick-header-button"
71     };
72
73
74     function init(grid) {
75       options = $.extend(true, {}, _defaults, options);
76       _grid = grid;
77       _handler
78         .subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)
79         .subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);
80
81       // Force the grid to re-render the header now that the events are hooked up.
82       _grid.setColumns(_grid.getColumns());
83     }
84
85
86     function destroy() {
87       _handler.unsubscribeAll();
88     }
89
90
91     function handleHeaderCellRendered(e, args) {
92       var column = args.column;
93
94       if (column.header && column.header.buttons) {
95         // Append buttons in reverse order since they are floated to the right.
96         var i = column.header.buttons.length;
97         while (i--) {
98           var button = column.header.buttons[i];
99           var btn = $("<div></div>")
100             .addClass(options.buttonCssClass)
101             .data("column", column)
102             .data("button", button);
103
104           if (button.showOnHover) {
105             btn.addClass("slick-header-button-hidden");
106           }
107
108           if (button.image) {
109             btn.css("backgroundImage", "url(" + button.image + ")");
110           }
111
112           if (button.cssClass) {
113             btn.addClass(button.cssClass);
114           }
115
116           if (button.tooltip) {
117             btn.attr("title", button.tooltip);
118           }
119
120           if (button.command) {
121             btn.data("command", button.command);
122           }
123
124           if (button.handler) {
125             btn.bind("click", button.handler);
126           }
127
128           btn
129             .bind("click", handleButtonClick)
130             .appendTo(args.node);
131         }
132       }
133     }
134
135
136     function handleBeforeHeaderCellDestroy(e, args) {
137       var column = args.column;
138
139       if (column.header && column.header.buttons) {
140         // Removing buttons via jQuery will also clean up any event handlers and data.
141         // NOTE: If you attach event handlers directly or using a different framework,
142         //       you must also clean them up here to avoid memory leaks.
143         $(args.node).find("." + options.buttonCssClass).remove();
144       }
145     }
146
147
148     function handleButtonClick(e) {
149       var command = $(this).data("command");
150       var columnDef = $(this).data("column");
151       var button = $(this).data("button");
152
153       if (command != null) {
154         _self.onCommand.notify({
155             "grid": _grid,
156             "column": columnDef,
157             "command": command,
158             "button": button
159           }, e, _self);
160
161         // Update the header in case the user updated the button definition in the handler.
162         _grid.updateColumnHeader(columnDef.id);
163       }
164
165       // Stop propagation so that it doesn't register as a header click event.
166       e.preventDefault();
167       e.stopPropagation();
168     }
169
170     $.extend(this, {
171       "init": init,
172       "destroy": destroy,
173
174       "onCommand": new Slick.Event()
175     });
176   }
177 })(jQuery);