Row Grouping

This page shows how to group your rows. It starts off with Auto Column Groups, the simplest way to configure row groups and then builds up into more advanced topics for row grouping.

Specifying Group Columns

To group rows by a particular column, mark the column you want to group with rowGroup=true. There is no limit on the number of columns that the grid can group by. For example, the following will group the rows in the grid by country and then sport: gridOptions.columnDefs = [ {headerName: "Country", field: "country", rowGroup: true}, {headerName: "Sport", field: "sport", rowGroup: true}, ];

To allow a column to be grouped when using the Tool Panel set enableRowGroup=true on the required columns. Otherwise you won't be able to drag and drop the columns to the grouping drop zone from the Tool Panel.

Auto Column Group

As you can see in the example below, as soon as there is at least on active row group, the grid will provide an additional column for displaying the groups in a tree structure, with expand/collapse navigation.

  • There is a group column at the left that lets you open/close the groups. It also shows the amount of rows grouped in brackets.
  • Sorting works out of the box in the group column. You can test this by clicking on the group column header.
  • The country and sport columns used for grouping are still shown as normal. You can hide them by adding hide: true to their colDef as illustrated in the Multi Auto Column example.

Multi Auto Column Group

The grid also lets you automatically create one column for each individual group. This is achieved by setting gridOptions.groupMultiAutoColumn = true. The following example illustrates this. Note that:

  • There is a group column displayed for each column that we are grouping by (in this case the country and year columns).
  • Sorting works out of the box in each of these group column. You can test this by clicking on the group column header.
  • The country and sport columns used for grouping are hidden so that we don't show redundant information. This is done by setting colDef.hide = true.

Configuring the Auto Group Column

You can specify your own configuration used by the auto group columns by providing a gridOptions.autoGroupColumnDef. This can be used to override any property as defined in the Columns documentation page

The auto columns generated by the grid use the ag-Grid provided group cell renderer. This means that gridOptions.autoGroupColumnDef can also be used to pass additional properties to further customise how your groups are displayed.

Check the cell rendering docs to see all the available parameters available to configure the group cell renderer.

The following example illustrates how you can configure the auto group columns. Note that:

  • For the purpose of simplification this example uses one Auto Row Group Column. If you were to use Multi Auto Group Column the configuration would be applied to all the generated columns
  • The header name of the group column is changed by setting in autoGroupColumnDef.headerName = 'CUSTOM!'
  • The count for each group is removed by setting autoGroupColumnDef.cellRendererParams.suppressCount = true
  • Each group has a select box by setting autoGroupColumnDef.cellRendererParams.checkbox = true
  • The group column has a custom comparator that changes the way sorting works, this is achieved by setting autoGroupColumnDef.cellRendererParams.comparator = function (left, right){...}. The custom comparator provided in the example changes the way the sorting works by ignoring the first letter of the group. To test this click on the header. When sorting desc you should see countries which second letter goes from Z..A, asc should show countries which second letter goes A..Z

Adding Values To Leaf Nodes

You may have noticed in the examples so far that the group columns don't produce values on the leaf nodes, the cells are empty. If you want to add values you can add a valueGetter or a field to the colDef and it will be used to render the leaf node.

A good side effect of this is that then you can turn on filtering on the group column which has values for the leaf node and then the filtering will be available based on these values.

The following example shows the easiest way to implement this with a single auto group column and a value getter in the autoGroupColumnDef that is returning the athlete column Note that:

  • To see the leaf node values, open any country and any year int the group column. Note how their leaf nodes are showing the value for the athlete column, this is achieved with a valueGetter: valueGetter: function (params){ return ? : '' }
  • Filtering is switched on so you can see how now you can filter the group column by athlete.

Adding leaf nodes data can also be achieved even if you provide your own group columns, this is illustrated in the following example. Note the following:

  • To see the leaf node values, open any country and any year group column. Note how their leaf nodes have values for the columns 'Country' and 'Year - Group', the default is not to have values for this cells.
  • Filtering is switched on so you can see how now you can filter the group column 'Country' and 'Year - Group' based on their leaf node values.
  • Country is providing the value to the leaf nodes via specifying the field property, it is also reusing the same column that is grouping by as the column to display that group
  • Year is providing the value to the leaf nodes via a value getter, this way we get to show the value from a different column, the athlete column. In this case we are using two different columns 'Year - Group' shows the year group and 'year' which is hidden hide:true specifies that we want to group by this column.
  • This is an example of a case where not using auto group columns lets us add custom behaviour to our grouping.

Group Cell Rendering

If you use the default group cell renderer provided by ag-grid, there are many parameters that can be passed to configure its behaviour, they are all explained in the Group Cell Renderer documentation. Please have a look at this docs if you are interested in finding our how to change the contents that are displayed in each grouped cell.

You can also configure the look & feel of the expan/contract buttons by specifying your own custom icons.

Specifying Row Group Order

By default, if you are using a column to display more than one group, the grid will order the groups based in the order in which you provide the columns. The following code snipped will group by country first, then sport second. columnDefs = [ // country listed first, gets grouped first {headerName: "Country", field: "country", rowGroup: true}, // sport listed second, gets grouped second {headerName: "Sport", field: "sport", rowGroup: true}, ];

To explicitly set the order of the grouping and not depend on the column order, then use rowGroupIndex instead of rowGroup as follows:

columnDefs = [ // index = 1, gets grouped second {headerName: "Country", field: "country", rowGroupIndex: 1}, // index = 0, gets grouped first {headerName: "Sport", field: "sport", rowGroupIndex: 0}, ];

The grid will order sort the columns based on the rowGroupIndex. The values can be any numbers that are sortable, they do NOT need to start at zero (or one) and the sequence can have gaps.

Using rowGroup=true is simpler and what most people will prefer using. You will notice that rowGroupIndex is used by the column API getColumnState() method as this cannot depend on the order of the column definitions.

The following examples shows using rowGroupIndex to set the order of the group columns. Year is grouped first and Country is grouped second.

Hide Open Parents

Depending on your preference, you may wish to hide parent rows when they are open. This gives the impression to the user that the children takes the place of the parent row. This feature only makes sense when groups are in different columns. To turn this feature on set groupHideOpenParents=true.

Below shows examples of this. Notice that each group row has aggregated values which are explained in a documentation page of their own. When the group is closed, the group row shows the aggregated result. When the group is open, the group row is removed and in its place the child rows are displayed. To allow closing the group again, the group column knows to display the parent group in the group column only (so you can click on the icon to close the group).

Example Hide Open Parents

The example below demonstrates hiding open parents using auto group columns. To help demonstrate, the grid is configured to shade the rows different colors for the different group levels, so when you open a group, you can see the background change indicating that the group row is no longer display, instead the children are in it's place.

Full Width Group Rows

Instead of having a column for showing the groups, you can dedicate the full row for showing details about the group. This can be preferred if you have a lot of information you want to say about the group.

The following example shows the first example in this page, the Auto Column Group example, using full width rows. Note that all that is necessary to achieve this it to add groupUseEntireRow:true to your gridOptions

Full Width Groups Rendering

It is possible to override the rendering of the group row using groupRowRenderer and groupRowInnerRenderer. Use groupRowRenderer to take full control of the row rendering, and provide a cellRenderer exactly how you would provide one for custom rendering of cells for non-groups.

The following pieces of code do the exact same thing: // option 1 - tell the grid to group by row, the grid defaults to using // the default group cell renderer for the row with default settings. gridOptions.groupUseEntireRow = true; // option 2 - this does the exact same as the above, except we configure // it explicitly rather than letting the grid choose the defaults. // we tell the grid what renderer to use (the built in renderer) and we // configure the default renderer with our own inner renderer gridOptions.groupUseEntireRow = true; gridOptions.groupRowRenderer: 'agGroupCellRenderer'; gridOptions.groupRowRendererParams: { innerRenderer: function(params) {return params.node.key;}, }; // option 3 - again the exact same. we allow the grid to choose the group // cell renderer, but we provide our own inner renderer. gridOptions.groupUseEntireRow = true; gridOptions.groupRowInnerRenderer: function(params) {return params.node.key;};

The above probably reads a bit confusing. So here are rules to help you choose:

  • If you are happy with what you get with just setting groupUseEntireRow = true, then stick with that, don't bother with the renderers.
  • If you want to change the inside of the renderer, but are happy with the expand / collapse etc of the group row, then just set the groupRowInnerRenderer.
  • If you want to customise the entire row, you are not happy with what you get for free with the group cell renderer, then set your own renderer with groupRowRenderer, or use groupRowRenderer to configure the default group renderer.

Here is an example of taking full control, creating your own renderer. In practice, this example is a bit useless, as you will need to add functionality to at least expand and collapse the group, however it demonstrates the configuration:

gridOptions.groupUseEntireRow = true; gridOptions.groupRowRenderer: function(params) {return params.node.key;};

This example takes full control also, but uses the provided group renderer but configured differently by asking for a checkbox for selection:

gridOptions.groupUseEntireRow = true; gridOptions.groupRowRenderer: 'agGroupCellRenderer'; gridOptions.groupRowRendererParams: { checkbox: true, // innerRenderer is optional, we could leave this out and use the default innerRenderer: function(params) {return params.node.key;}, }

Below shows an example of aggregating, then using the entire row to give a summary.

We use Components for the groupRowRenderer in this example.

Full Width Group Rows - Embedding

You have two choices when using full width groups using the property embedFullWidthRows as follows:

  • embedFullWidthRows = false: The group row will always span the width of the grid including pinned areas and is not impacted by horizontal scrolling. This is the most common usage and thus the default. The only drawback is that for some browsers (IE in particular), as you scroll vertically, the group row will lag behind the other rows.
  • embedFullWidthRows = true: The group row will be split into three sections for center, pinned left and pinned right. This is not ideal but works much faster with no IE issues.

So you might ask which one to use? The answer is the first one (just leave the property out, it's defaulted to false) unless you want to avoid IE performance issues.

The examples below demonstrate embedFullWidthRows on and off as follows:

  • Both grids have columns pinned left and right.
  • Both grids have group rows spanning the grid width.
  • The top grid as embedFullWidthRows=false, the bottom grid has embedFullWidthRows=true.

So with this setup, you will notice the following difference:

  • In the top grid, the group rows are not impacted by the pinning. In the bottom grid, the groups are truncated if you make the Athlete & Year columns to small, as the groups are sitting in the pinned section.
  • In the bottom grid, if you unpin the columns (via the column menu) then the group jumps to the center.

If you are using custom group row rendering (explained below) and embedFullWidthRows = true, the panel you are rendering in is provided via the pinned parameter.

Unbalanced Groups

If there are rows containing null or undefined values for the column that is being grouped then these rows will not be grouped. We refer to this scenario as Unbalanced Groups in that there is a mix of groups and rows as siblings. The following example demonstrates:

  • Data is grouped by column 'State'. Rows are either grouped by state 'New York', 'California' or not grouped.
  • Removing the grouping shows that the non grouped rows have no 'State' value.

If you do not want rows with null or undefined to be left out of groups, but want a group created to contain these empty values, then change your data and replace the null and undefined values with something (eg the string 'Empty' or a string with a blank space character i.e. ' ').

Grouping API

To expand or contract a group via the API, you first must get a reference to the rowNode and then call rowNode.setExpanded(boolean). This will result in the grid getting updated and displaying the correct rows. For example, to expand a group with the name 'Zimbabwe' would be done as follows: gridOptions.api.forEachNode(function(node) { if (node.key==='Zimbabwe') { node.setExpanded(true); } });

Calling node.setExpanded() causes the grid to get redrawn. If you have many nodes you want to expand, then it is best to set node.expanded=true directly, and then call api.onGroupExpandedOrCollapsed() when finished to get the grid to redraw the grid again just once.

Grouping Complex Objects with Keys

If your rowData has complex objects that you want to group by, then the default grouping will convert each object to "[object object]" which will be useless to you. Instead you need to get the grid to convert each object into a meaningful string to act as the key for the group. You could add a 'toString' method to the objects - but this may not be possible if you are working with JSON data. To get around this, use colDef.keyCreator, which gets passed a value and should return the string key for that value.

The example below shows grouping on the county, with country an object within each row.

// row item has complex object for country rowItem = { athlete: 'Michael Phelps', country: { name: 'United States', code: 'US' } .... } // the column definition for country has keyCreator colDef = { headerName: "Country", field: "country", keyCreator: function(params) { return; } ... }

Grouping Footers

If you want to include a footer with each group, set the property groupIncludeFooter to true. The footer is displayed as the last line of the group when then group is expanded - it is not displayed when the group is collapsed.

The footer by default will display the word 'Total' followed by the group key. If this is not what you want, then use the footerValueGetter option. The following shows two snippets for achieving the same, one using a function, one using an expression.

// use a function to return a footer value cellRenderer:'agGroupCellRenderer', cellRendererParams: { footerValueGetter: function(params) { return 'Total (' + params.value + ')'}, }} // use an expression to return a footer value. this gives the same result as above cellRenderer:'agGroupCellRenderer', cellRendererParams: { footerValueGetter: '"Total (" + x + ")"' }}

When showing the groups in one column, the aggregation data is displayed in the group header when collapsed and only in the footer when expanded (ie it moves from the header to the footer). To have different rendering, provide a custom groupInnerCellRenderer, where the renderer can check if it's a header or footer.

The example below uses aggregation which is explained in the next section but included here as footer rows only make sense when used with aggregation.

Keeping Group State

If using transactions or delta updates, then you do not need to be concerned with keeping group state. When using transactions or delta updates, the group state is not changed.

When you set new data into the group by default all the group open/closed states are reset. If you want to keep the original state, then set the property rememberGroupStateWhenNewData=true. The example below demonstrates this. Only half the data is shown in the grid at any given time, either the odd rows or the even rows. Hitting the 'Refresh Data' will set the data to 'the other half'. Note that not all groups are present in both sets (eg 'Afghanistan' is only present in one group) and as such the state is not maintained. A group like 'Australia' is in both sets and is maintained.

Removing Single Children

If your data has groups with only one child, then it can make sense to collapse these groups as there is no benefit to the user creating groups with just one child, it's arguably waste of space.

To turn this feature on set either groupRemoveSingleChildren=true or groupRemoveLowestSingleChildren=true.

  • groupRemoveSingleChildren: Removes groups from display if they only have one child.
  • groupRemoveLowestSingleChildren: Removes groups from display if they only have one child and the groups is at the lowest level (ie contains leaf nodes).

The example below shows this feature. Note the following:

  • Normal: Shows the rows as normal, nothing is removed. All groups have their children count in brackets after the group.
  • Remove Single Children: Removes single children using the property groupRemoveSingleChildren=true. All groups with just one child are remove.
  • Remove Lowest Single Children: Removes single children using the property groupRemoveLowestSingleChildren=true. All groups for the 'City' column with just one child are remove. The 'City' column is the lowest level group, so it's the only group candidate to be removed when one child.

Filtering does not impact what groups get removed. For example if you have a group with two children, the group is not removed, even if you apply a filter that removes one of the children. This is because ag-Grid does grouping first and then applies filters second. If you change the filter, only the filter is reapplied, the grouping is not reapplied. The properties groupRemoveSingleChildren, groupRemoveLowestSingleChildren and groupHideOpenParents are mutually exclusive, you can only pick one. Technically it doesn't make sense to mix these. Mixing these three will put you down a black hole so deep not even Stephen Hawking will be able to save you.

Suppress Group Row

By suppressing the group row you don't give users the ability to close the groups by themselves, but the rows are grouped and the other functionalities take the grouping into account. Sorting, for example, will sort by group.

Creating Your Own Group Display Columns

In all the previous examples the grid is in charge of generating the column's that display the groups, these columns are called auto group columns.

You can prevent the generation of the auto group columns and take control over which columns display which groups. This is useful if you want to have a finer control over how your groups are displayed.

We advise against using your own group columns. Only do this if the Auto Group Columns do not meet your requirements. Otherwise defining your own group columns will add unnecessary complexity to your code.

To disable the auto group columns set gridOptions.groupSuppressAutoColumn = true. When you do this, you will be in charge of configuring which columns show which groups.

In order to make a column display a group, you need to configure the property coldef.showRowGroup for that column.

coldef.showRowGroup can be configured in two different fashions.

  • To tell this column to show all the groups: coldef.showRowGroup= true
  • To tell this column to show the grouping for a particular column. If you want to do this you need to know the colId of the column that you want to show the group by and set coldef.showRowGroup= colId

If you do specify coldef.showRowGroup you are going to also tell this column how to display the contents of this group, the easiest way to do this is by using the out of the box group cell renderer cellRenderer:'agGroupCellRenderer'

This illustrates how to configure an specific column to show the groups generated by the country column

coldefs:[ // The column we are grouping by, it is also hidden. {headerName: "Country", field: "country", width: 120, rowGroup:true, hide:true}, // We appoint this column as the column to show the country groups. // note that we need to provide an appropiate cell renderer. // in this case we are using the out of the box group cell renderer. {headerName: "Country - group", showRowGroup='country', width: 120, cellRenderer:'agGroupCellRenderer'}, ]

The following example shows how to appoint individual columns to show individual groups

The following example shows how to display all the groups in a single column

The last example of explicitly setting groups shows an alternative for Hide Open Parents. The example below demonstrates hiding open parents using explicit group columns.

Remember these examples are achieving the same that you can achieve with the auto groups columns, but their configuration is not as straight forward. We are keeping this for edge cases and for backwards compatibility for when we only supported this style of configuration.

Grid Grouping Properties

Grouping has the following grid properties (set these as grid properties, e.g. on the gridOptions, not on the columns):

Property Description
groupUseEntireRow If grouping, set to true or false (default is false). If true, a group row will span all columns across the entire width of the table. If false, the cells will be rendered as normal and you will have the opportunity to include a grouping column (normally the first on the left) to show the group. See Full Width Group Rows.
groupDefaultExpanded If grouping, set to the number of levels to expand by default. Eg 0 for none, 1 first level only, etc. Default is 0 (expand none). Set to -1 for expand everything. See example Removing Single Children.
autoGroupColumnDef Allows specifying the group 'auto column' if you are not happy with the default. If grouping, this column def is included as the first column definition in the grid. If not grouping, this column is not included. See Configuring the Auto Group Column.
groupSuppressAutoColumn If true, the grid will not swap in the grouping column when grouping is enabled. Use this if you want complete control on the column displayed and don't want the grids help. In other words, you already have a column in your column definitions that is responsible for displaying the groups. See Configuring the Auto Group Column.
groupMultiAutoColumn If using auto column, set to true to have each group in its own column separate column, eg if group by Country then Year, two auto columns will be created, one for country and one for year. See Multi Auto Column Group.
groupSuppressRow If true, the group row won't be displayed and the groups will be expanded by default with no ability to expand / contract the groups. Useful when you want to just 'group' the rows, but not add parent group row to each group. See Suppress Group Row.
groupSelectsChildren When true, if you select a group, the the children of the group will also get selected. See Group Selection.
groupIncludeFooter If grouping, whether to show a group footer when the group is expanded. If true, then by default, the footer will contain aggregate data (if any) when shown and the header will be blank. When closed, the header will contain the aggregate data regardless of this setting (as footer is hidden anyway). This is handy for 'total' rows, that are displayed below the data when the group is open, and alongside the group when it is closed See Grouping Footers.
groupSuppressBlankHeader If true, and showing footer, aggregate data will be displayed at both the header and footer levels always. This stops the possibly undesirable behaviour of the header details 'jumping' to the footer on expand.
groupSelectsFiltered If using groupSelectsChildren, then only the children that pass the current filter will get selected. See Group Selection.
groupRemoveSingleChildren Set to true to collapse groups that only have one child. See Remove Single Children.
groupRemoveLowestSingleChildren Set to true to collapse lowest level groups that only have one child. See Remove Single Children.
groupHideOpenParents Set to true to hide parents that are open. When used with multiple columns for showing groups, it can give more pleasing user experience. See Group Hide Open Parents.
rowGroupPanelShow When to show the 'row group panel' (where you drag rows to group) at the top. Default is never. Set to either 'always' or 'onlyWhenGrouping'. See Tool Panel Example.

Grid Grouping Callbacks

Callback Description
groupRowRenderer, groupRowRendererParams If grouping, allows custom rendering of the group cell. Use this if you are not happy with the default presentation of the group. This is only used when groupUseEntireRow=true. This gives you full control of the row, so the grid will not provide any default expand / collapse or selection checkbox. See section on cellRendering for details on params.
groupRowInnerRenderer Similar to groupRowRenderer, except the grid will provide a default shell for row which includes an expand / collapse function. The innerRenderer is responsible for just the inside part of the row. There is no groupRowInnerRendererParams as the groupRowRendererParams are reused for both.