Reputation: 1645
Is there a way to show grand totals in Slickgrid with grouping?
I found following:
1) In documentation Implementing a totals row via a data provider. But then I can't use DataView and grouping features.
2) There is plugin for SlickGrid called Slickgrid totals plugin. But it doesn't allow to use grouping features.
Upvotes: 0
Views: 2668
Reputation: 114
- Add TotalsDataProvider function
function TotalsDataProvider(dataView, columns) {
var totals = {};
var totalsMetadata = {
// Style the totals row differently.
cssClasses: "totals",
columns: {}
};
// Make the totals not editable.
for (var i = 0; i < columns.length; i++) {
totalsMetadata.columns[i] = { editor: null };
}
this.getLength = function() {
return dataView.getLength() + 1;
}
this.getItem = function(index) {
return (index < dataView.getLength()) ? dataView.getItem(index) : totals;
};
// Some group-functions from DataView
this.setRefreshHints = function(hints) {
return dataView.setRefreshHints(hints);
};
this.collapseGroup = function(varArgs) {
return dataView.collapseGroup(varArgs);
};
this.expandGroup = function(varArgs) {
return dataView.expandGroup(varArgs);
};
this.updateTotals = function() {
var columnIdx = columns.length;
while (columnIdx--) {
var column = columns[columnIdx];
if (!column.hasTotal) { // Just add in your column "hasTotal: true"
continue;
}
var total = 0;
var i = dataView.getLength();
while (i--) {
total += (dataView.getItem(i)[column.field] || 0);
}
totals[column.field] = total;
}
};
this.getItemMetadata = function(index) {
return (index != dataView.getLength()) ? dataView.getItemMetadata(index) : totalsMetadata;
};
this.updateTotals();
}
- Add option "hasTotal: true" in your columns. For example:
var columns = [
{id: "id", name: "Index", field: "id", hasTotal: true},
{id: "title", name: "Title", field: "title"},
{id: "duration", name: "Duration", field: "duration", hasTotal: true},
{id: "%", name: "% Complete", field: "percentComplete", hasTotal: true},
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"},
{id: "effort-driven", name: "Effort Driven", field: "effortDriven"}
];
- Change grid variable and add dataProvider variable above:
//grid = new Slick.Grid("#myGrid", dataView, columns, options);
var dataProvider = new TotalsDataProvider(dataView, columns);
grid = new Slick.Grid("#myGrid", dataProvider, columns, options);
- Every time you change data (by filtering or by grid.onCellCange) you need update total data:
// The data has changed - recalculate the totals.
dataProvider.updateTotals();
// Rerender the totals row (last row).
grid.invalidateRow(dataProvider.getLength() - 1);
grid.render();
Upvotes: 1
Reputation: 1645
I found some workaround. The algorithm is as follows:
noGrouping:true
DataView
usingdataView.setItems(JSONDataArray)
In slick.dataview.js
in function addTotals
, after line:
g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];
add:
if(g.rows[0].noGrouping) {
g.collapsed = true;
}
So the group of grand totals is always collapsed
If needed, add some formatting in slick.groupitemmetadataprovider.js
for function defaultGroupCellFormatter
Upvotes: 0