Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

persistence does not work when editing cell #180

Open
RunQi-Han opened this issue May 8, 2023 · 3 comments
Open

persistence does not work when editing cell #180

RunQi-Han opened this issue May 8, 2023 · 3 comments
Labels
bug something broken P3 not needed for current cycle

Comments

@RunQi-Han
Copy link

RunQi-Han commented May 8, 2023

Based on the Docs:. We would like to make the data persist after editing the table. The persisted_props might be rowData. However, the persistence does not work as in the sample below:

"""
Accessing Row Data in an editable grid
"""
import dash
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State,ctx
import plotly.express as px
import pandas as pd
import json


app = Dash(__name__)

df = px.data.medals_wide()


app.layout = html.Div(
    [
        dcc.Markdown(id= 'dummy-input', children="Example of using `rowData` in a callback with an editable grid and added persistence to cell"),
        dag.AgGrid(
            id="editing-grid",
            columnDefs=[{"field": i} for i in df.columns],
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"editable": True},
            persistence=True,
            persisted_props=['rowData'],     
        ),
    ],
    style={"margin": 20},
)

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

A workaround is to use dcc.Store() as below:

"""
Accessing Row Data in an editable grid
"""
import dash
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State,ctx
import plotly.express as px
import pandas as pd
import json

app = Dash(__name__)

df = px.data.medals_wide()

app.layout = html.Div(
    [
        dcc.Markdown(id= 'dummy-input', children="Example of using `rowData` in a callback with an editable grid and added persistence to cell"),
        dag.AgGrid(
            id="editing-grid",
            columnDefs=[{"field": i} for i in df.columns],
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"editable": True},
        ),
        dcc.Store(id='memory',storage_type = 'session'),
        html.Div(id="editing-grid-output2"),
    ],
    style={"margin": 20},
)

@app.callback(
    Output("memory", "data"),
    Output("editing-grid", "rowData"),
    Input("editing-grid", "cellValueChanged"),
    State("editing-grid", "rowData"),
    State("memory", "data"),
)
def update(cell,rows,saved_rows):
    if saved_rows is None:
        saved_rows = df.to_dict("records")
    if cell is None:
        return saved_rows, saved_rows
    else:
        return rows,rows

if __name__ == "__main__":
    app.run_server(debug=True)
@BSd3v
Copy link
Collaborator

BSd3v commented Jul 27, 2023

Hello @RunQi-Han,

This is actually an issue with how the grid manipulates the rowData, they manipulate the variable in place, so there is no way for dash to distinguish that the rowData has changed.

Unfortunately, this might be something that we cant do because it could cause a performance hit to separate them.

May revisit later.

For now, this work around for persistence will need to mainstream.

@RunQi-Han
Copy link
Author

Hello @RunQi-Han,

This is actually an issue with how the grid manipulates the rowData, they manipulate the variable in place, so there is no way for dash to distinguish that the rowData has changed.

Unfortunately, this might be something that we cant do because it could cause a performance hit to separate them.

May revisit later.

For now, this work around for persistence will need to mainstream.

@BSd3v thanks for your explanation.

@BSd3v BSd3v added the documentation written for humans label Oct 13, 2023
@celia-lm
Copy link

Hi! Here's an updated version of the workaround that takes advantage of Patch() (partial property updates) to improve performance, especially with large datasets:

import dash
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State, ctx, Patch, callback
import plotly.express as px
import pandas as pd

app = Dash(__name__)

df = px.data.gapminder()
# df["id"] = df.index # optional

app.layout = html.Div(
    [
        dag.AgGrid(
            id="editing-grid",
            columnDefs=[{"field": i} for i in df.columns if i != 'id'],
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            defaultColDef={"editable": True},
            #getRowId="params.data.id" # optional
        ),
        dcc.Store(id='memory',storage_type = 'session', data=[]),
    ],
    style={"margin": 20},
)

@callback(
    Output("memory", "data"),
    Output("editing-grid", "rowData"),
    Input("editing-grid", "cellValueChanged"),
    State("memory", "data")
    # it's important that prevent_initial_call=False (the default)
)
def update(cells, edits):

    row_id_var = 'rowIndex' # you could use rowId instead

    if cells :
        cells_info = [{k:c[k] for k in [row_id_var, 'colId', 'value']} for c in cells]
        # you may want to include some logic to check if previous edits have been made to the same cells and remove those
        # keeping old edits won't cause a problem anyway
        edits += cells_info
        return edits, dash.no_update
    
    else :
        saved_rows = Patch()
        for e in edits: 
            index = e[row_id_var] 
            saved_rows[index][e['colId']] = e['value'] 
        return dash.no_update, saved_rows

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

@gvwilson gvwilson assigned gvwilson and unassigned gvwilson Jul 27, 2024
@gvwilson gvwilson changed the title [Bug] persistence does not work when editing cell persistence does not work when editing cell Aug 13, 2024
@gvwilson gvwilson added bug something broken P3 not needed for current cycle and removed documentation written for humans labels Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P3 not needed for current cycle
Projects
None yet
Development

No branches or pull requests

4 participants