Deleting Rows in Dash AG Grid
This question came up in another topic, so I decided to make it a separate post.
Here are several different ways to delete rows in Dash AG Grid. This post will demo:
- Using the
deleteSelectedRows
prop in a callback - Creating a column of delete buttons ( like in DataTable)
- Using
rowTransactions
prop in a callback.
1. Delete selected rows button
This method uses a button to delete selected rows in a callback, It makes it easy for the user to delete multiple rows. See the the post on all the different ways you can select rows in Dash AG Grid.
You simply create a grid with selectable rows, then have a button that triggers a callback to sent to the deleteSelectedRows
prop to True
.
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, callback
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
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("Delete Selected", id="button"),
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
dashGridOptions={"rowSelection":"multiple"},
),
],
style={"margin": 20},
)
@callback(
Output("grid", "deleteSelectedRows"),
Input("button", "n_clicks"),
prevent_initial_call=True
)
def selected(_):
return True
2. Delete button component in a cell (like Dash DataTable)
See more information on using components in cells in the Dash AG Grid docs
import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
df=df.head(10)
columnDefs = [
{
"headerName": "",
"cellRenderer": "DeleteButton",
"lockPosition":'left',
"maxWidth":35,
"filter": False,
'cellStyle': {'paddingRight': 0, 'paddingLeft': 0},
},
{"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "age", "maxWidth": 100},
{"field": "country"},
{"field": "year", "maxWidth": 120},
{"field": "date"},
{"field": "sport"},
{"field": "total"},
]
defaultColDef = { "sortable": True, "resizable": True, "filter": True}
app.layout = html.Div(
[
dag.AgGrid(
id="grid",
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
dashGridOptions={"rowSelection": "multiple", "suppressRowClickSelection": True},
),
],
style={"margin": 20},
)
if __name__ == "__main__":
app.run(debug=True)
"""
Place the following in the dashAgGridComponentFunctions.js file in the assets folder
---------------
var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};
dagcomponentfuncs.DeleteButton = function (props) {
function onClick() {
props.api.applyTransaction({ remove: [props.node.data] })
}
return React.createElement('button', {onClick}, "X");
};
"""
3. Delete Rows in a callback using rowTransaction
An efficient way to update data in the grid (including deleting rows) is to use rowTransaction
The rows must have row ids and It’s only necessary to specify the ids to delete.
This example shows how to delete rows when the grid does not have selectable rows. To illustrate, it uses a button to delete all rows where the year is 2012.
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, 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
defaultColDef = {"flex": 1, "minWidth": 150, "sortable": True, "resizable": True, "filter": True}
app.layout = html.Div(
[
html.Button("Delete 2012", id="year"),
html.Button("Undo", id="undo"),
dag.AgGrid(
id="grid",
columnDefs=[{"field": i} for i in df.columns],
rowData=df.to_dict("records"),
defaultColDef=defaultColDef,
getRowId="params.data.id",
),
],
style={"margin": 20},
)
@callback(
Output("grid", "rowTransaction"),
Input("year", "n_clicks"),
prevent_intial_call=True,
)
def delete_rows(_):
dff = df[df['year'] == 2012]
# it's only necessary to include the row ids
ids = dff[["id"]]
return {"remove": ids.to_dict("records")}
@callback(
Output("grid", "rowData"),
Input("undo", "n_clicks"),
prevent_intial_call=True,
)
def undo(_):
return df.to_dict("records")
if __name__ == "__main__":
app.run(debug=True)