Selecting Rows in Dash AG Grid
Some question have come up recently about selected rows and here is more information that has not yet made it’s way into the dash docs.
Note - Be sure to check the official dash-docs for updates.
The selectedRows
prop can be set 3 ways:
- sending the rowData of the rows you want selected
- using row ids, for example:
{"ids": ["1", "3", "5"]}
- using a function, for example
{"function": "params.data.total > '5'"}
Select Rows - using rowData
The example in the dash docs for Preslected Rows shows how to select rows by passing the rowData to the selectedRows
prop. This works, but it can be slow if you want to preselect a lot of rows.
Here is an updated version that preselects the first 400 rows and uses row ids for better performance. Learn more about row ids in the dash docs. See the difference in performance by running this example both with and without this line: getRowId="params.data.id"
import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
df["id"]= df.index
columnDefs = [
{"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "age", "maxWidth": 100},
{"field": "country"},
{"field": "year", "maxWidth": 120},
{"field": "date"},
{"field": "sport"},
{"field": "total"},
]
defaultColDef = {"flex": 1, "minWidth": 150, "sortable": True, "resizable": True, "filter": True}
app.layout = html.Div(
[
dcc.Markdown("This grid has preselected rows"),
dag.AgGrid(
id="preselect-checkbox-grid",
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
dashGridOptions={"rowSelection":"multiple"},
# preselect first 400 rows
selectedRows= df.head(400).to_dict("records"),
# Try commenting out the line below -- you will see a big lag before the rows are selected
getRowId="params.data.id",
),
],
style={"margin": 20},
)
if __name__ == "__main__":
app.run(debug=True)
Select rows using the row ids or a function
You can get even better performance by selecting rows using a list of row ids.
This example uses row ids to select the first 50 rows. It uses a function to select all rows where the year is 2012.
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, callback, ctx
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
df["id"] = df.index
columnDefs = [
{"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "age", "maxWidth": 100},
{"field": "country"},
{"field": "year", "maxWidth": 120},
{"field": "date"},
{"field": "sport"},
{"field": "total"},
]
defaultColDef = {"flex": 1, "minWidth": 150, "sortable": True, "resizable": True, "filter": True}
app.layout = html.Div(
[
html.Button("Select top 50", id="top"),
html.Button("Select 2012", id="year"),
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
dashGridOptions={"rowSelection": "multiple"},
getRowId="params.data.id",
),
],
style={"margin": 20},
)
@callback(
Output("grid", "selectedRows"),
Input("top", "n_clicks"),
Input("year", "n_clicks"),
prevent_intial_call=True,
)
def pre_select_rows(*_):
if ctx.triggered_id == "top":
# use row ids to select rows
return {"ids": [str(i) for i in range(50)]}
if ctx.triggered_id == "year":
# use a function to select rows
return {"function": "params.data.year == '2012'"}
if __name__ == "__main__":
app.run(debug=True)
Select or Deselect rows using the Grid API
If you want ultimate control over the select and deselection of rows, you can use the Grid API in a clientside callback.
In this example, the user can select multiple rows, then click a button to exclude certain rows (in this case the year 2012 is deselected.
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, clientside_callback
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
df["id"] = df.index
columnDefs = [
{"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "age", "maxWidth": 100},
{"field": "country"},
{"field": "year", "maxWidth": 120},
{"field": "date"},
{"field": "sport"},
{"field": "total"},
]
defaultColDef = {"flex": 1, "minWidth": 150, "sortable": True, "resizable": True, "filter": True}
app.layout = html.Div(
[
html.Button("Deselect 2012", id="not2012"),
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
dashGridOptions={"rowSelection":"multiple"},
getRowId="params.data.id",
),
],
style={"margin": 20},
)
clientside_callback(
"""async function (n) {
gridApi = await dash_ag_grid.getApiAsync("grid")
gridApi.forEachNode((rowNode, index) => {
if (rowNode.data.year == '2012') {
rowNode.setSelected(false);
}
});
return dash_clientside.no_update
}""",
Output("grid", "id"),
Input("not2012", "n_clicks"),
prevent_initial_call=True
)
if __name__ == "__main__":
app.run(debug=True)
Other ways to select rows
This page from the preliminary docs has not made it the official dash-docs (yet). It shows how to select all rows or just filtered rows. Plus it shows how to select only rows on the current page. See examples here:
dag-docs