This section covers Row Grouping in the Server-Side Row Model (SSRM).
Row Grouping is enabled in the grid via the rowGroup
column definition attribute.
The example below shows how to group rows by 'country':
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */>
</ag-grid-angular>
this.columnDefs = [
{ field: 'country', rowGroup: true },
{ field: 'sport' },
{ field: 'year' },
];
For more configuration details see the section on Row Grouping.
The actual grouping of rows is performed on the server when using the SSRM. When the grid needs more rows it makes a
request via getRows(params)
on the Server-Side Datasource with metadata containing
grouping details.
The properties relevant to Row Grouping in the request are shown below:
// IServerSideGetRowsRequest
{
// row group columns
rowGroupCols: ColumnVO[];
// what groups the user is viewing
groupKeys: string[];
... // other params
}
Note in the snippet above the property rowGroupCols
contains all the columns (dimensions) the grid is
grouping on, e.g. 'Country', 'Year'. The property groupKeys
contains the list of group keys selected,
e.g. ['Argentina', '2012']
.
The example below demonstrates server-side Row Grouping. Note the following:
rowGroup=true
defined on their column definitions. This tells the grid there are two levels of grouping, one for Country and one for Sport.rowGroupCols
and groupKeys
properties in the request are used by the server to perform grouping.It is possible to have rows open as soon as they are loaded. To do this implement the grid callback isServerSideGroupOpenByDefault
.
// Example implementation
function isServerSideGroupOpenByDefault(params) {
var rowNode = params.rowNode;
var isZimbabwe = rowNode.field == 'country' && rowNode.key == 'Zimbabwe';
return isZimbabwe;
}
It may also be helpful to use the Row Node API getRoute()
to inspect the route of a row node.
Below shows isServerSideGroupOpenByDefault()
and getRoute
in action. Note the following:
By default the group nodes stick to the top of the Grid, to disable this behaviour, set the suppressGroupRowsSticky
property to true. This behaviour applies to all row group levels.
To enable Row Group Footers, set the groupIncludeFooter
property to true. Note that the total footer is not supported by the SSRM.
Row group footers can also be used with groupDisplayType='multipleColumns
, as demonstrated in the example below.
It is possible to expand and collapse all group rows using the expandAll()
and collapseAll()
grid API's.
// Expand all group rows
this.gridApi.expandAll();
// Collapse all group rows
this.gridApi.collapseAll();
Calling expandAll()
and collapseAll()
will impact all loaded group nodes, including those not visible due to their containing group been closed. This means there could potentially be a huge number of groups expanded, so this method should be used very wisely to not create massive amount of server requests and loading a large amount of data.
Calling expandAll()
and collapseAll()
will have no impact on rows yet to be loaded.
To open only specific groups, e.g. only groups at the top level, then use the forEachNode()
callback and open / close the row using setExpanded()
as follows:
// Expand all top level row nodes
this.gridApi.forEachNode(node => {
if (node.group && node.level == 0) {
node.setExpanded(true);
}
});
The example below demonstrates these techniques. Note the following:
Clicking 'Expand All' will expand all loaded group rows. Doing this when the grid initially loads will expand all Year groups. Clicking it a second time (after Year groups have loaded) will cause all Year groups as well as their children Country groups to be expanded - this is a heavier operation with 100's of rows to expand.
Clicking 'Collapse All' will collapse all rows.
Clicking 'Expand Top Level Only' will expand Years only, even if more group rows are loaded..
By default, the grid will not show row counts beside the group names. If you do want row counts, you need to implement the getChildCount(dataItem)
callback for the grid. The callback provides you with the row data; it is your application's responsibility to know what the child row count is. The suggestion is you set this information into the row data item you provide to the grid.
<ag-grid-angular
[getChildCount]="getChildCount"
/* other grid options ... */>
</ag-grid-angular>
this.getChildCount = data => {
// here child count is stored in the 'childCount' property
return data.childCount;
};
It is possible the data provided has composite objects, in which case it's more difficult for the grid to extract group names. This can be worked with using value getters or embedded fields (i.e. the field attribute has dot notation).
In the example below, all rows are modified so that the rows look something like this:
// sample contents of row data
{
// country field is complex object
country: {
name: 'Ireland',
code: 'IRE'
},
// year field is complex object
year: {
name: '2012',
shortName: "'12"
},
// other fields as normal
...
}
Then the columns are set up so that country uses a valueGetter
that uses the field with dot notation, i.e. data.country.name
By default the grid will fully purge the grid when impacted by the change in filters. The grid can be configured to only refresh when the group has been directly impacted by enabling serverSideOnlyRefreshFilteredGroups
. Be aware, this can mean your grid may have empty group rows. This is because the grid will not refresh the groups above the groups it deems impacted by the filter.
In the example below, note the following:
Gold
, Silver
or Bronze
fully purges the grid, this is because they have aggregations applied.Year
column does not purge the entire grid, and instead only refreshes the Year
group rows.serverSideOnlyRefreshFilteredGroups
, note that if you apply a filter to Year
with the value 1900
, no leaf rows exist in any group.Continue to the next section to learn about SSRM Pivoting.