Skip to content

Row Grouping: Dynamic setting of "rowGroup" flag buggy in version 32.3.2 #416

Closed

Description

@nesseltier

Hey everyone,

I'm currently in the process of updating the Dash AG Grid version used by our application from 31.3.1 to 32.3.2. We have an enterprise license and use row grouping in our grids, with the option to toggle the group setting via switch in the UI. So, we basically have a callback that listens to the toggle's checked and sets the rowGroup flag accordingly.

While this worked just as expected in the prior version, I noticed that after the update, this has become a problem. If I try to activate the row grouping, the grid will start a brief animation, but snap back to its initial state and keep being ungrouped. Only after I deactivate and activate the switch once again, the row grouping is applied. This is also the other way round: if I want to disable the row grouping, I also need two tries.
It looks a bit like changing the rowGroup the first time triggers the animation of the layout change, but is then interrupted by something else.

To eliminate any other factors that could interfere with this in our application source code, I have created a mini app (see code below). It is derived from the Dash AG Grid docs' Row Groupings example. The described behaviour is the same however, that's why I wanted to reach out to you.

import os

import dash_ag_grid as dag
import dash_mantine_components as dmc
import pandas as pd
from dash import Dash, Input, Output, State, callback, dcc, html

app = Dash()

df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv")

columnDefs = [
    {"field": "country"},
    {"field": "year"},
    {"field": "athlete"},
    {"field": "age"},
    {"field": "date"},
    {"field": "sport"},
    {"field": "total"},
]

app.layout = html.Div(
    [
        dcc.Markdown("Demonstration of row groupings in a Dash AG Grid."),
        dcc.Markdown("This grid groups first by country and then by year."),
        dmc.MantineProvider(
            children=[
                dmc.Switch(
                    label="Toggle Grouping",
                    id="grouping-toggle",
                    checked=False,
                    withThumbIndicator=False,
                ),
                dmc.Space(h=20),
            ],
            id="dummy-mantine-provider",
        ),
        dag.AgGrid(
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            dashGridOptions={"rowSelection": {"mode": "multiRow"}, "animateRows": False},
            defaultColDef=dict(filter=True),
            id="dummy-grid",
            # Row groupings is an ag-grid Enterprise feature.
            # A license key should be provided if it is used.
            # License keys can be passed to the `licenseKey` argument of dag.AgGrid
            enableEnterpriseModules=True,
            licenseKey=os.getenv("AG_GRID_LICENSE_KEY"),
        ),
    ]
)

@callback(
    Output("dummy-grid", "columnDefs"),
    Input("grouping-toggle", "checked"),
    State("dummy-grid", "columnDefs"),
    prevent_initial_call=True,
)
def toggle_row_grouping(checked, current_column_defs):
    updated_column_defs = []
    for idx, col in enumerate(current_column_defs):
        if idx < 2:
            # Toggle grouping for 'country' and 'year' cols
            col["rowGroup"] = checked
        updated_column_defs.append(col)
    return updated_column_defs


if __name__ == "__main__":
    app.run(debug=True)

Activity

  1. changed the title [-]Row Grouping: Dynamic setting of "rowGroup" flag not reliable anymore in version 32.3.2[/-] [+]Row Grouping: Dynamic setting of "rowGroup" flag buggy in version 32.3.2[/+] on Nov 24, 2025
  2. BSd3v commented on Nov 24, 2025

    @BSd3v
    Collaborator

    Hello @nesseltier,

    Until my PR gets merged and released, you can use this workaround:

    @callback(
        Output("dummy-grid", "columnDefs"),
        Output('dummy-grid', 'columnState'),
        Input("grouping-toggle", "checked"),
        State("dummy-grid", "columnDefs"),
        State('dummy-grid', 'columnState'),
        prevent_initial_call=True,
    )
    def toggle_row_grouping(checked, current_column_defs, cs):
        updated_column_defs = []
        for idx, col in enumerate(current_column_defs):
            if idx < 2:
                # Toggle grouping for 'country' and 'year' cols
                col["rowGroup"] = checked
            updated_column_defs.append(col)
        for c in cs:
            if c["colId"] in ["country", "year"]:
                if checked:
                    c["rowGroup"] = True
                else:
                    # Remove grouping properties when toggled off
                    del c['rowGroup']
                    del c['rowGroupIndex']
        return updated_column_defs, cs
    

    This forces the changes in the columnState that you are performing by grouping and ungrouping.

  3. nesseltier commented on Nov 26, 2025

    @nesseltier
    Author

    Thank you for the quick reply @BSd3v! The workaround did the trick for me. Now I wonder whether it is possible to not collapse single leaf children into their own subgroups?

    Image Image

    As of right now in the mini app, the children of the group "Zimbabwe" are also grouped. I tried to add the "groupHideParentOfSingleChild" with "leafGroupsOnly" (see https://www.ag-grid.com/javascript-data-grid/grouping-data/) to the dashGridOptions, but this does not seem to work. Can you point me into the right direction?

    Thanks again!

  4. BSd3v commented on Dec 3, 2025

    @BSd3v
    Collaborator

    Hello @nesseltier,

    This worked for me:

    import os
    
    import dash_ag_grid as dag
    import dash_mantine_components as dmc
    import pandas as pd
    from dash import Dash, Input, Output, State, callback, dcc, html
    
    app = Dash()
    
    df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv")
    
    columnDefs = [
        {"field": "country"},
        {"field": "year"},
        {"field": "athlete"},
        {"field": "age"},
        {"field": "date"},
        {"field": "sport"},
        {"field": "total"},
    ]
    
    app.layout = html.Div(
        [
            dcc.Markdown("Demonstration of row groupings in a Dash AG Grid."),
            dcc.Markdown("This grid groups first by country and then by year."),
            dmc.MantineProvider(
                children=[
                    dmc.Switch(
                        label="Toggle Grouping",
                        id="grouping-toggle",
                        checked=False,
                        withThumbIndicator=False,
                    ),
                    dmc.Space(h=20),
                ],
                id="dummy-mantine-provider",
            ),
            dag.AgGrid(
                columnDefs=columnDefs,
                rowData=df.to_dict("records"),
                dashGridOptions={"rowSelection": {"mode": "multiRow"}, "animateRows": False,
                                 "groupHideParentOfSingleChild": "leafGroupsOnly"},
                defaultColDef=dict(filter=True),
                id="dummy-grid",
                # Row groupings is an ag-grid Enterprise feature.
                # A license key should be provided if it is used.
                # License keys can be passed to the `licenseKey` argument of dag.AgGrid
                enableEnterpriseModules=True,
                licenseKey=os.getenv("AG_GRID_LICENSE_KEY"),
            ),
        ]
    )
    
    @callback(
        Output("dummy-grid", "columnDefs"),
        Output('dummy-grid', 'columnState'),
        Input("grouping-toggle", "checked"),
        State("dummy-grid", "columnDefs"),
        State('dummy-grid', 'columnState'),
        prevent_initial_call=True,
    )
    def toggle_row_grouping(checked, current_column_defs, cs):
        updated_column_defs = []
        for idx, col in enumerate(current_column_defs):
            if idx < 2:
                # Toggle grouping for 'country' and 'year' cols
                col["rowGroup"] = checked
            updated_column_defs.append(col)
        for c in cs:
            if c["colId"] in ["country", "year"]:
                if checked:
                    c["rowGroup"] = True
                else:
                    # Remove grouping properties when toggled off
                    del c['rowGroup']
                    del c['rowGroupIndex']
        return updated_column_defs, cs
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions