summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/example-grouping.html24
-rw-r--r--slick.dataview.js39
-rw-r--r--slick.groupitemmetadataprovider.js140
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