diff options
-rw-r--r-- | examples/example-grouping.html | 24 | ||||
-rw-r--r-- | slick.dataview.js | 39 | ||||
-rw-r--r-- | slick.groupitemmetadataprovider.js | 140 |
3 files changed, 157 insertions, 46 deletions
diff --git a/examples/example-grouping.html b/examples/example-grouping.html index 8de867e..eceb485 100644 --- a/examples/example-grouping.html +++ b/examples/example-grouping.html @@ -75,6 +75,7 @@ <script src="../plugins/slick.cellrangeselector.js"></script> <script src="../plugins/slick.cellselectionmodel.js"></script> <script src="../slick.grid.js"></script> + <script src="../slick.groupitemmetadataprovider.js"></script> <script src="../slick.dataview.js"></script> <script src="../controls/slick.pager.js"></script> <script src="../controls/slick.columnpicker.js"></script> @@ -217,29 +218,20 @@ d["effortDriven"] = (i % 5 == 0); } - - dataView = new Slick.Data.DataView(); + var groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider(); + dataView = new Slick.Data.DataView({ + groupItemMetadataProvider: groupItemMetadataProvider + }); grid = new Slick.Grid("#myGrid", dataView, columns, options); + // register the group item metadata provider to add expand/collapse group handlers + grid.registerPlugin(groupItemMetadataProvider); + grid.setSelectionModel(new Slick.CellSelectionModel()); var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options); - grid.onClick.subscribe(function(e, args) { - var item = this.getDataItem(args.row); - if (item && item instanceof Slick.Group && $(e.target).hasClass("slick-group-toggle")) { - if (item.collapsed) { - this.getData().expandGroup(item.value); - } - else { - this.getData().collapseGroup(item.value); - } - - e.stopImmediatePropagation(); - e.preventDefault(); - } - }); grid.onSort.subscribe(function(e, args) { sortdir = args.sortAsc ? 1 : -1; diff --git a/slick.dataview.js b/slick.dataview.js index 97ab3b5..cc916b4 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -19,9 +19,14 @@ * * Relies on the data item having an "id" property uniquely identifying it. */ - function DataView() { + function DataView(options) { var self = this; + var defaults = { + groupItemMetadataProvider: new Slick.Data.GroupItemMetadataProvider() + }; + + // private var idProperty = "id"; // property holding a unique row id var items = []; // data by index @@ -54,16 +59,8 @@ var onRowsChanged = new Slick.Event(); var onPagingInfoChanged = new Slick.Event(); - // TODO: move into options - function defaultGroupCellFormatter(row, cell, value, columnDef, dataContext) { - return "<span class='slick-group-toggle " + (dataContext.collapsed ? "collapsed" : "expanded") + "'></span>" + - dataContext.title; - } + options = $.extend(true, {}, defaults, options); - // TODO: move into options - function defaultTotalsCellFormatter(row, cell, value, columnDef, dataContext) { - return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(dataContext, columnDef)) || ""; - } function beginUpdate() { suspend = true; @@ -242,29 +239,12 @@ // overrides for group rows if (item.__group) { - return { - selectable: false, - focusable: true, - cssClasses: "slick-group", - columns: { - 0: { - colspan: "*", - formatter: defaultGroupCellFormatter, - editor: null - } - } - }; + return options.groupItemMetadataProvider.getGroupRowMetadata(item); } // overrides for totals rows if (item.__groupTotals) { - return { - selectable: false, - focusable: false, - cssClasses: "slick-group-totals", - formatter: defaultTotalsCellFormatter, - editor: null - }; + return options.groupItemMetadataProvider.getTotalsRowMetadata(item); } return null; @@ -556,7 +536,6 @@ }; } - function MinAggregator(field) { var min; diff --git a/slick.groupitemmetadataprovider.js b/slick.groupitemmetadataprovider.js new file mode 100644 index 0000000..68430eb --- /dev/null +++ b/slick.groupitemmetadataprovider.js @@ -0,0 +1,140 @@ +(function($) { + $.extend(true, window, { + Slick: { + Data: { + GroupItemMetadataProvider: GroupItemMetadataProvider + } + } + }); + + + /*** + * Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView. + * This metadata overrides the default behavior and formatting of those rows so that they appear and function + * correctly when processed by the grid. + * + * This class also acts as a grid plugin providing event handlers to expand & collapse groups. + * If "grid.registerPlugin(...)" is not called, expand & collapse will not work. + * + * @class GroupItemMetadataProvider + * @module Data + * @namespace Slick.Data + * @constructor + * @param options + */ + function GroupItemMetadataProvider(options) { + var _grid; + var _defaults = { + groupCssClass: "slick-group", + totalsCssClass: "slick-group-totals", + groupFocusable: true, + totalsFocusable: false, + toggleCssClass: "slick-group-toggle", + toggleExpandedCssClass: "expanded", + toggleCollapsedCssClass: "collapsed", + enableExpandCollapse: true + }; + + options = $.extend(true, {}, _defaults, options); + + + function defaultGroupCellFormatter(row, cell, value, columnDef, item) { + if (!options.enableExpandCollapse) { + return item.title; + } + + return "<span class='" + options.toggleCssClass + " " + + (item.collapsed ? options.toggleCollapsedCssClass : options.toggleExpandedCssClass) + + "'></span>" + item.title; + } + + function defaultTotalsCellFormatter(row, cell, value, columnDef, item) { + return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef)) || ""; + } + + + function init(grid) { + _grid = grid; + _grid.onClick.subscribe(handleGridClick); + _grid.onKeyDown.subscribe(handleGridKeyDown); + + } + + function destroy() { + if (_grid) { + _grid.onClick.unsubscribe(handleGridClick); + _grid.onKeyDown.unsubscribe(handleGridKeyDown); + } + } + + function handleGridClick(e, args) { + var item = this.getDataItem(args.row); + if (item && item instanceof Slick.Group && $(e.target).hasClass(options.toggleCssClass)) { + if (item.collapsed) { + this.getData().expandGroup(item.value); + } + else { + this.getData().collapseGroup(item.value); + } + + e.stopImmediatePropagation(); + e.preventDefault(); + } + } + + // TODO: add -/+ handling + function handleGridKeyDown(e, args) { + if (options.enableExpandCollapse && (e.which == $.ui.keyCode.SPACE)) { + var activeCell = this.getActiveCell(); + if (activeCell) { + var item = this.getDataItem(activeCell.row); + if (item && item instanceof Slick.Group) { + if (item.collapsed) { + this.getData().expandGroup(item.value); + } + else { + this.getData().collapseGroup(item.value); + } + + e.stopImmediatePropagation(); + e.preventDefault(); + } + } + } + } + + function getGroupRowMetadata(item) { + return { + selectable: false, + focusable: options.groupFocusable, + cssClasses: options.groupCssClass, + columns: { + 0: { + colspan: "*", + formatter: defaultGroupCellFormatter, + editor: null + } + } + }; + } + + function getTotalsRowMetadata(item) { + return { + selectable: false, + focusable: options.totalsFocusable, + cssClasses: options.totalsCssClass, + formatter: defaultTotalsCellFormatter, + editor: null + }; + } + + + + return { + "init": init, + "destroy": destroy, + "getGroupRowMetadata": getGroupRowMetadata, + "getTotalsRowMetadata": getTotalsRowMetadata + }; + } +})(jQuery);
\ No newline at end of file |