Callback for Deleting a Row in a Data Table

Hi there!!

Want to be able to trigger a callback when the user deletes a row in a data table.

Specifically- when the user clicks the x button- I would like to pull information about the row the user chose to delete- and use that to delete information in the backend of my system.

The most similar thing I could find was the adding or remove rows section in this link:
Editable DataTable | Dash for Python Documentation | Plotly but I don’t think that’s exactly the functionality I’m looking for. What would be the best way to do this?

Thanks!!

3 Likes

Hi there- posted this a couple of weeks ago and have yet to get a response!

Hi @shrub,

You can use the previous_data and data to deduce the removed data, at least that is the method I was able to use. Below is a simple program that demonstrates this.

That said, you might want to add some optimizations to improve performance, perhaps converting all the values of a unique column into a set and doing a set difference.

import dash
from dash.dependencies import Input, Output, State
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

app = dash.Dash(__name__)

app.layout = html.Div([

    dash_table.DataTable(
        id='table',
        columns=[{
            'name': 'Column {}'.format(i),
            'id': 'column-{}'.format(i),
            'deletable': True,
            'editable_name': True
        } for i in range(1, 5)],
        data=[
            {'column-{}'.format(i): (j + (i-1)*5) for i in range(1, 5)}
            for j in range(5)
        ],
        editable=True,
        row_deletable=True
    ),

    html.Div(id='output')
])

@app.callback(Output('output', 'children'),
              [Input('table', 'data_previous')],
              [State('table', 'data')])
def show_removed_rows(previous, current):
    if previous is None:
        dash.exceptions.PreventUpdate()
    else:
        return [f'Just removed {row}' for row in previous if row not in current]


if __name__ == '__main__':
    app.run_server(debug=True)
3 Likes

To add on to my previous comment about performance, say column-1 was a unique key, then you would get a much more performant run-time by doing:

set([i['column-1'] for i in prev]) - set([i['column-1'] for i in cur])

And then extracting the details using that row key. Of course this is all dependent on your data, but thought I would throw out the suggestion.

2 Likes

Thanks a bunch for the help Max!!! Didn’t realize that the data table had a previous_data property- clever use of that here :smile:

Glad it worked out :+1:

p.s React Developer Tools is your friend. That is how I noticed the prop.

2 Likes

I’ve a tightly related scenario: I’ve an editable datatable and get the number of table rows when a row has been added via a button (it’s callback). I keep track of the row count via the Storage component. However I’ve not found a way to decrement the stored row count when an x in the editable datatable has been pressed yet. Any suggestions?

This seems to be outdated??

What has changed? Is there a way to delete records from both the data table and database without resorting to work arounds?

1 Like

Data is a list of dicts in the form [{col: value, col: value}, {col: value, col: value}] or is it jsonified?

Hi @mbkupfer - thank you so much. That works well every time I click the x button to delete.

Just having another question - so I have another button Add Row, and when I clicked that to input details for each column, the show_removed_rows will also track the previous same row input showing as part of the deleted rows too. So let’s say I inputed the values for the first column, and when I tabbed to the 2nd column to provide values, it will recognise the same row with 1st column value input as deleted. And when I keep doing this, it will add up the rows deleted, though they are for the same row. Is there any way to avoid that?