Deleting Rows in Dash AG Grid

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:

  1. Using the deleteSelectedRows prop in a callback
  2. Creating a column of delete buttons ( like in DataTable)
  3. 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.

ag-grid-delete-selected-rows




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

ag-grid-delete-row-like-datatable


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)

6 Likes

Hey @AnnMarieW , love the examples here :slight_smile:

I implemented the one with the button on the row and it works great for updating the table, however it doesn’t seem to be updating any Dash properties to trigger a callback when the row is removed. Do you have an idea of how to go about it?

Hello @RenaudLN,

What happens if you pass “async”: False in the rowTransaction? Does the rowData update in dash?

I tried the following but no update to rowData

props.api.applyTransaction({ remove: [props.node.data], async: false })

Using the underlying api with that is going to be sync, to be async it would be applyTransactionAsync, we do this in the rowTransaction by using the keyword async which defaults to True.

The other thing that will update is virtualRowData. Issue here is that it updates for other reasons as well.