Dash AG Grid - Row Selection

Decently simple situation but can’t figure out why. If I render a grid (vendor_table) in a drawer

            dmc.Drawer(
                id="drawer-admin-settings",
                opened=False,
                position="left",
                size="50%",
                title="System Settings",
                #zIndex=5000,
                children=[
                    vendor_table(),

the row selection on click does not work but if I just render the same vendor_table in the main dashboard area row_selection works just fine. So my assumption is when rendered in the drawer something with the click events isn’t working correctly. The box that is clicked highlights upon click but the row is never selected. Well never is a strong statement I have seen it row select 1/20 times…I am sure there are some smarter people out there who know why!

1 Like

Hi @jazzleblue and welcome to the Dash communithy :slight_smile:

Can you please try including the withinPortal=False prop to the dmc.Drawer

Just curious to see if that click event listener works with that setting.

Hi – Unfortunately it doesn’t work this way either.

Hi @jazzleblue

Try running this example - it works fine for me:


import dash_ag_grid as dag
import pandas as pd
from dash import Dash, html, callback, Output, Input, dcc, dash, _dash_renderer
import dash_mantine_components as dmc
_dash_renderer._set_react_version("18.2.0")


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


columnDefs = [
    {"field": "athlete", "checkboxSelection": True},
    {"field": "year"},
    {"field": "sport"},
    {"field": "total"},
]

grid = html.Div(
    [
        dag.AgGrid(
            id="row-selection-selected-rows",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"filter": True},
            dashGridOptions={"rowSelection": "multiple", "suppressRowClickSelection": True, "animateRows": False},
            selectedRows=df.head(2).to_dict("records")
        ),
        html.Pre(id="pre-row-selection-selected-rows", style={'text-wrap': 'wrap'})
    ],
)


drawer = html.Div(
    [
        dmc.Button("Open Drawer", id="drawer-demo-button"),
        dmc.Drawer(
            title="Drawer Example",
            id="drawer-simple",
            padding="md",
            children=grid,
        ),
    ]
)


app = Dash(external_stylesheets=dmc.styles.ALL, suppress_callback_exceptions=True)

app.layout = dmc.MantineProvider(drawer)


@callback(
    Output("drawer-simple", "opened"),
    Input("drawer-demo-button", "n_clicks"),
    prevent_initial_call=True,
)
def drawer_demo(n_clicks):
    return True


@callback(
    Output("pre-row-selection-selected-rows", "children"),
    Input("row-selection-selected-rows", "selectedRows"),
)
def output_selected_rows(selected_rows):
    selected_list = [f"{s['athlete']} ({s['year']})" for s in selected_rows]
    return f"You selected the athlete{'s' if len(selected_rows) > 1 else ''}:\n{', '.join(selected_list)}" if selected_rows else "No selections"


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




Hi – Yes, your example works and very much appreciate sharing.

Well not what I ever thought it would be.

Seems that if there are multiple callbacks attached to the grid it will break the row selection by mouse click if “suppressRowClickSelection”: True….why this is so is a mystery to me. The row selection does work in any situation using the checkboxes.

To be clear this breaks the mouse click row selection…

@callback(
    Output("vendor-table", "rowData"),
    Input("drawer-admin-settings", "opened"),
    prevent_initial_call=True,
)
def load_vendor_data(opened):
    if opened:
        logger.info("Loading vendor data")
        try:
            api_service.update_token(current_user.token)

            vendor_data = api_service.get("/teststand/vendors")
            logger.debug(f"Loaded {len(vendor_data)} vendors")
            return vendor_data
        except Exception as e:
            logger.error(f"Error loading vendor data: {e}")
    return []


@callback(
    Output("vendor-table", "dashGridOptions"),
    Input("vendor-filter", "value"),
    prevent_initial_call=True,
)
def update_filter(filter_value):
    return {"quickFilterText": filter_value or ""}

Hello @jazzleblue,

Assuming that your data is refreshing, you should be using getRowId in order to maintain selections, otherwise, as your data updates it won’t maintain.

Also, you are removing the grid rowData when the drawer is closed, this will end up clearing any selections.

Hi. What I can reproduce happens all with the drawer being open and never closed. I do agree that if the drawer is closed the data will refresh and lose any selections. I can work around this but still seems like strange behavior. The data only gets refreshed in the table at drawer open and is not being refreshed in the background.

Scenario 1

  1. update_filter callback is commented out
  2. Refresh app
  3. Page Load
  4. Open drawer
  5. row selection by mouse click works

Scenario 2

  1. update_filter callback is not commented out
  2. Refresh app
  3. Page load
  4. Open drawer
  5. row selection by mouse click does not work

The second callback is the only change between the two scenarios.

Is anything attached or altering that value for the quickfilter?

You are absolutely right. That quickfilter callback is causing the issue. Grid functions well with all fo the other logic turned back on without the quickfilter callback. There are no other references to the text input witch calls it anywhere in the code base. So I am trying to think about how to debug it further…

Solved.

@callback(
    Output("vendor-table", "dashGridOptions"),
    Input("vendor-filter", "value"),
    prevent_initial_call=True,
)
def update_filter(filter_value):
    newFilter = Patch()
    newFilter["quickFilterText"] = filter_value
    return newFilter

Patch…appreciate the entertainment of my issue. Cheers.

Oh, yes. Patch is much better. Haha.

I guess you were removing the rowSelection argument. :rofl:

Yes, yes I was. :man_facepalming:
Good news is there is no singularity in the simulation.

1 Like