Row Selection and Callbacks

Select/deselect rows and remove selected rows using Callbacks.

selectedRows Parameter

The Grid parameter selectedRows can be used to:

The selectedRows parameter can be set 3 ways:

Note that selecting hundreds of rows using rowData of the rows to select can show lags, setting getRowId can improve
the performance. Using row ids or a function to select hundreds of rows generally provides even better performance.
See Improve Selection Performance.

Simple Example

In the following example selectedRows is used:

```python
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, callback
import pandas as pd

app = Dash()

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

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

app.layout = html.Div(
    [
        html.Button("Select 'Natalie Coughlin' rows", id="btn-row-selection-callbacks-selected-rows"),
        dag.AgGrid(
            id="grid-row-selection-callbacks-selected-rows",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"filter": True},
            dashGridOptions={
                "animateRows": False,
                "rowSelection": {'mode': 'multiRow'},
            },
            selectedRows=df.head(5).to_dict("records")
        ),
        html.Pre(id="pre-row-selection-callbacks-selected-rows", style={'textWrap': 'wrap'})
    ]
)


@callback(
    Output("pre-row-selection-callbacks-selected-rows", "children"),
    Input("grid-row-selection-callbacks-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"


@callback(
    Output("grid-row-selection-callbacks-selected-rows", "selectedRows"),
    Input("btn-row-selection-callbacks-selected-rows", "n_clicks"),
    prevent_initial_call=True,
)
def select_rows(_):
    return df[df['athlete'] == 'Natalie Coughlin'].to_dict("records")


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

This second example shows how to generate a popup using Dash Bootstrap Components when a user selects a row in the
grid.

```python
import dash_ag_grid as dag
from dash import Dash, Input, Output, html, ctx, no_update, callback
import dash_bootstrap_components as dbc

app = Dash(__name__, external_stylesheets=[dbc.themes.SPACELAB])

columnDefs = [{"field": i} for i in ["make", "model", "price"]]

rowData = [
    {"make": "Toyota", "model": "Celica", "price": 35000},
    {"make": "Ford", "model": "Mondeo", "price": 32000},
    {"make": "Porsche", "model": "Boxster", "price": 72000},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="grid-row-selection-callbacks-popup",
            rowData=rowData,
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            dashGridOptions={
                "animateRows": False,
                "rowSelection": {'mode': 'single'},
            },
        ),
        dbc.Modal(
            [
                dbc.ModalHeader("More information about selected row"),
                dbc.ModalBody(id="row-selection-callbacks-modal-content"),
                dbc.ModalFooter(dbc.Button("Close", id="row-selection-callbacks-modal-close", className="ml-auto")),
            ],
            id="row-selection-callbacks-modal",
        ),
    ]
)


@callback(
    Output("row-selection-callbacks-modal", "is_open"),
    Output("row-selection-callbacks-modal-content", "children"),
    Input("grid-row-selection-callbacks-popup", "selectedRows"),
    Input("row-selection-callbacks-modal-close", "n_clicks"),
)
def open_modal(selection, _):
    if ctx.triggered_id == "row-selection-callbacks-modal-close":
        return False, no_update
    if selection:
        return True, "You selected " + ", ".join(
            [
                f"{s['make']} (model {s['model']} and price {s['price']})"
                for s in selection
            ]
        )

    return no_update, no_update


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

Improve Selection Performance

This example shows the selection performance selecting hundreds of rows when setting selectedRows with the following
options:

The button can be used to select/unselect the rows, and we can see the time to perform the selection.

Note that the function used in this example {'function': 'params.data.age == 23'} selects 691 rows. To compare the
results, the other options are also set to select 691 rows.

The first option can take a few seconds to perform the selection. The second greatly improves the performance.
The third and the final options provide even better performance.

```python
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, callback, dcc, no_update, State
import pandas as pd
import time

app = Dash()

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

df["id"] = df.index.astype(str)

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

app.layout = html.Div(
    [
        html.Button("Select Rows", id="btn-row-selection-callbacks-performance"),
        dcc.RadioItems(
            id='radio-row-selection-callbacks-performance',
            options={
                'rowdata': "selectedRows = df.head(691).to_dict('records')",
                'rowdata+getrowid': "selectedRows = df.head(691).to_dict('records') and getRowId = 'params.data.id'",
                'ids': "selectedRows = {'ids': [str(i) for i in range(691)]}",
                'function': "selectedRows = {'function': 'params.data.age == 23'}",
            },
            value='rowdata',
            style={'margin': '10px 0px'}
        ),
        html.Div('Timer: 0s', id='div-row-selection-callbacks-performance'),
        dag.AgGrid(
            id="grid-row-selection-callbacks-performance",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef={"filter": True},
            dashGridOptions={
                "animateRows": False,
                "rowSelection": {
                    'mode': 'multiRow',
                    'checkboxes': False,
                    'headerCheckbox': False
                },
            },
        ),
        dcc.Store(id="store-row-selection-callbacks-performance")
    ]
)


@callback(
    Output("grid-row-selection-callbacks-performance", "selectedRows"),
    Output("grid-row-selection-callbacks-performance", "getRowId"),
    Output("btn-row-selection-callbacks-performance", "children"),
    Output("store-row-selection-callbacks-performance", "data"),
    Input("btn-row-selection-callbacks-performance", "n_clicks"),
    State("radio-row-selection-callbacks-performance", "value"),
    prevent_initial_call=True,
)
def select_deselect_rows(n, value):
    if n % 2 == 0:
        return [], no_update, "Select Rows", no_update
    else:
        get_row_id = None
        if 'rowdata' in value:
            selected_rows = df.head(691).to_dict("records")
            get_row_id = "params.data.id" if 'getrowid' in value else None
        elif value == 'ids':
            selected_rows = {"ids": [str(i) for i in range(691)]}
        else:
            selected_rows = {"function": "params.data.age == 23"}
        return selected_rows, get_row_id, "Deselect Rows", time.time()


@callback(
    Output("div-row-selection-callbacks-performance", "children"),
    Input("grid-row-selection-callbacks-performance", "selectedRows"),
    State("store-row-selection-callbacks-performance", "data"),
    prevent_initial_call=True,
)
def update_timer(selected_rows, start_time):
    return f'Timer: {(time.time() - start_time):.3f}s' if selected_rows else no_update


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

Remove Selected Rows

Dash AG Grid provides the deleteSelectedRows parameter that can be used to easily remove the selected rows. When set
to True under the hood it will trigger
a transaction
gridApi.applyTransaction({remove: selection})

In the following example, try to select a few rows and then click on the button to remove them.

```python
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, callback
import pandas as pd

app = Dash()

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

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

app.layout = html.Div(
    [
        html.Button("Remove Selected Rows", id="btn-row-selection-callbacks-remove"),
        dag.AgGrid(
            id="grid-row-selection-callbacks-remove",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef={"filter": True},
            dashGridOptions={"rowSelection": {'mode': 'multiRow'}},
        ),
    ]
)


@callback(
    Output("grid-row-selection-callbacks-remove", "deleteSelectedRows"),
    Input("btn-row-selection-callbacks-remove", "n_clicks"),
    prevent_initial_call=True,
)
def remove_selected_rows(_):
    return True


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