DataGrid - Grouping

Grouping rows

It's possible to group several rows together by a common value they contain. This can be specified by using the controlled groupBy prop - or its uncontrolled version, defaultGroupBy.
It's easier to get started by using defaultGroupBy since you don't have to hook onGroupByChange callback prop and update the <ReactDataGrid /> when there are changes. You can also use drag-and-drop to reorder group by columns. Or you can click the remove icon to inactivate grouping by a specific column.
In the example below, data is grouped by the column Permission to call. By dragging the column header on the upper area, you can group by others column as well.
A nice feature of the <ReactDataGrid> is the ability to have sticky group rows - use the boolean stickyGroupRows prop to configure the desired behaviour for your app.
Another nice feature is the groupColumn prop, which allows showing a dedicated column for grouping.
The group column can be customized, just like the checkboxColumn or other special columns.
Note that clicking the grouping toolbar buttons sorts the column just like clicking the normal column header would. In addition, you can un-group by clicking the remove icon or by dragging the toolbar item to the grid header area to a position in order to get the desired column order.
If you don't want a certain column to be draggable in the grouping toolbar, specify column.groupBy=false. In the previous example, notice that you cannot group by email.
Columns used in grouping are not displayed by default. This can be customized by specifying hideGroupByColumns=false.
If you want to enable grouping, but without a default group column, use defaultGroupBy=[].

Sticky group rows

Sticky group rows is a new feature of the <ReactDataGrid />. It allows you to have groups stick at the top of the viewport while scrolling, even when multiple levels of grouping are applied.

Controlled groupBy

In the previous example grouping was uncontrolled and defaultGroupBywas used.
In this section we're showing how you can use the controlled groupBy and onGroupByChange to achieve controlled behavior.
Whe using controlled groupBy you will need to update its value when onGroupByChange(newGroupBy) is called so the UI is updated accordingly.

Server-side grouping

Grouping can also be performed server-side, but for this you need to send from the server the records in the correct grouping order. See the example below for server-side grouping, pagination and sorting working together.

Grouping summaries

The <ReactDataGrid /> can display summaries for row groups - the summaries can be computed for each specific column or can be at group-level - more details in the examples and paragraphs below.
We introduce the concept of groupSummaryReducer - which are simple objects with the following props:
  • initialValue - the initial value to be used for the summary computation - generally a number/string/etc
  • reducer(accumulator, currentValue) - the reducer function - basically computes the summary from the accumulated value (at first call, this will equal the initialValue) and the current value for the item at which we are doing the computation
  • complete(accumulatedValue, array) - can be used for doing one last computation at the end of the iteration - for example useful for computing the average of a value. The first argument is the accumulated value, while the second is the array on which the summary was computed against
Here's an example - suppose we have a list of world cities, grouped by country - each city will have a population property, and we want to sum up the total population of a country - so we need to add the population of each city in a country. We would use a groupSummaryReducer on the population column, that would look like this:
  name: 'population',
  groupSummaryReducer: {
    initialValue: 0,
    reducer: (acc, population) => acc + population
However, if we want to compute the average city population, the summary reducer would also need a complete function.
  name: 'population',
  groupSummaryReducer: {
    initialValue: 0,
    reducer: (acc, population) => acc + population,
    complete: (value, arr) => arr.length ? value/arr.length : 0
When used for a specific column the second argument to the reduce function is the actual value of the corresponding column property for a given dataSource item.
However, groupSummaryReducer can also be defined as a prop directly on the grid - the resulting summary will be available in custom render functions defined for columns, when the group rows are being rendered. The computed summary will be available in the data.groupSummary object inside the column.render function.
When groupSummaryReducer is defined at the grid level, the second arg to the groupSummaryReducer.reducer function is the whole data object of the row, since it's no longer related to a certain column.
The column group summary will be displayed by default if you use groupColumn. If you don't use groupColumn, then you need a custom renderer for the group title - see the example below - or you can use showGroupSummaryRow documented in the next section below.
When groupColumn is used, the group summary row is not displayed.
For each group row, the renderGroupTitle function (and also the column custom render function, if you want to define one) gives you access to the group summaries via the row data object groupColumnSummary object - which will have properties for each column that defines a groupSummaryReducer.
For customizing the values displayed inside the group column, you cannot simply specify a custom render function - since that would not render the expand/collapse group arrow (of course you can do this, but most of the time you don't need to).
Instead, you can specify groupColumn.renderGroupValue, which will be called for the group column cells - but only for those that are inside group rows!
As the example above shows, in custom render functions defined for columns, when the group row is being rendered, you have access to the group summaries via the data.groupColumnSummary object, which has a key for each of the columns that define a column.groupSummaryReducer.
Also data.groupSummary is available in the render function in case you have definedgroupSummaryReducer at grid-level - see the example below.

Showing group summary rows

Another nice feature is the possibility to show a summary row for each group - see the demo below.
Group summary rows are only visible when there is no groupColumn.
You can control the position of the group summary row, by using 'start'|'end' instead of a boolean. Also, since the group summary is rendered in the specific column, you can add a custom renderer for that case - see the demo below.