Chimango Chisuwo
Chimango Chisuwo

Reputation: 113

Dash datatable calculations using active cell callback trigger to update the source datatable

I have a data table whose goal is to perform excel like computations and display results in a column within the same table.

Using the active cell trigger I am able to perform the computation in pandas by getting the table data dict but I am however having trouble with updating the datatable in question. I have been getting the nonetype error when the callback attempts to update the datatable. Below is my datatable and callback code any help will be appreciated.

dash_table.DataTable(
                            editable=True,  
                            row_deletable=True, 
                            sort_action="native", 
                            sort_mode="single",  
                            # filter_action="native", 
                            column_selectable="single",
                            row_selectable="multi",
                            page_action="none",  .
                            style_table={
                                "margin": "auto%",
                                "width": "80%",
                                "overflowY": "auto",
                            },
                            id="request_table",
                            data=df.to_dict("records"),
                            columns=[
                                {
                                    "name": "Item_ID",
                                    "id": "Item_ID",
                                    "deletable": False,
                                    "renamable": False,
                                    "editable": True,
                                },
                                {
                                    "name": "Price",
                                    "id": "Price",
                                    "deletable": True,
                                    "renamable": True,
                                    "editable": True,
                                    "type": "numeric",
                                },
                                {
                                    "name": "Quantity",
                                    "id": "Quantity",
                                    "deletable": False,
                                    "renamable": False,
                                    "editable": True,
                                    "type": "numeric",
                                },
                                {
                                    "name": "Line Total",
                                    "id": "Line_Total",
                                    "deletable": False,
                                    "renamable": False,
                                    "editable": False,
                                    "type": "numeric",
                                },
                            ]
                            # active_cell=initial_active_cell,
                        ),
@app.callback(
    [Output("request_table", "data")],
    [Output("request_table", "columns")],
    Input("request_table", "active_cell"),
    State("request_table", "data"),
)
def getActiveCell(active_cell, rows):
    if active_cell:
        datacalc = datax.from_dict(rows)
        datacalc["Line_Total"] = datacalc["Price"] * datacalc["Quantity"]
        data = datacalc.to_dict("records")

        # data = list(itertools.chain(datacalc))

        return data

Upvotes: 1

Views: 1647

Answers (1)

wen tse yang
wen tse yang

Reputation: 100

I modified an example from the dash document. The callback rewrite the data using the defined rule and it can be used as the output. Just need to be cautious that the row values would become string so data type needs change before calculation.

from dash import Dash, dash_table, html
from dash.dependencies import Input, Output

app = Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='editing-table-data',
        columns=[{
            'name': 'Column {}'.format(i),
            'id': 'column-{}'.format(i)
        } for i in range(1, 5)],
        data=[
            {'column-{}'.format(i): i for i in range(1, 5)}
            for j in range(5)
        ],
        editable=True
    )
])

@app.callback(Output('editing-table-data', 'data'),
              Input('editing-table-data', 'data'),
              prevent_initial_call=True)
def display_output(rows):
    for row in rows:
        # update the data using a newly defined rule
        if all([cell != '' for cell in row.values()]):
            row['column-2'] = int(row['column-1']) * 10 + 1

    return rows

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

Upvotes: 2

Related Questions