Show old selections in Ag Grid after reload/ reupload

Hi,

I have a dropdown from which users can select between 2 tables, both of which show up as Dash AG Grid and the rows are selectable.
I want to create a program in which the following works:

  • User selects a table (lets say Table 1) and row 1

  • User selects Table 2 from dropdown and selects row 3

  • User selects Table 1 and the old selection is visible (checkmark active)

The idea was to use dcc.Store to store the selections and match them with the rows of the tables. However, dcc.Store clears when the tables are switched.

Here is the code:

import dash
from dash import dcc, html, Input, Output, State
import dash_ag_grid as dag
import pandas as pd


app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(['Table 1', 'Table 2'], 'NYC', id='dropdown'),

    html.Div(id="grid_div"),

    dcc.Store(id="selected", storage_type = 'local')
])



@app.callback(
    Output('grid', 'children', allow_duplicate=True),
    Input('dropdown', 'value'),
    prevent_initial_call=True
    
)
def clear_output(value):
    if value:
        return []


@app.callback(
    Output('grid_div', 'children'),
    Input('dropdown', 'value'),
    prevent_initial_call=True
    
)
def read_1(value):
    if value == "Table 1":
        df = pd.read_csv('table1.csv')
        print(df)
    elif value == "Table 2": 
        df = pd.read_csv('table2.csv')
        print(df)
    else:
        return "Something went wrong"

    
    column_defs = []
    for col_index, col_name in enumerate(df.columns):
        column_defs.append(
            {
                "headerName": f"{col_name}",
                "field": f"{col_name}",
                "width": 500,
                "resizable": False,
                "checkboxSelection": True if col_index == 0 else False,
                "filter": True,
            }
        )

    grid = dag.AgGrid(
        id="grid",
        className="ag-theme-alpine border",
        rowData=df.to_dict("records"),
        columnDefs=column_defs,
        columnSize="sizeToFit",
        dashGridOptions={
            "domLayout": "autoHeight",
            "columnHoverHighlight": True,
            "rowSelection": "multiple",
        },
        style={"height": "100%", "fontSize": "20px"},
    )
    return grid

@app.callback(
    Output("selected", "data"),
    Input("grid","selectedRows"),
    State("selected", "data"),
    prevent_initial_call=True
)
def store(row, existing):
    print(row)
    if row is not None:
        for item in row:
            existing.append(item)
        print(existing)
        return existing



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

Hello @subodhpokhrel7,

Are the two grids going to have the same identifiers between them, if so, I recommend using getRowId to set these up, then switching the rowData should maintain your selections.

If that is not the case, then I suggest in your store that you create two dictionaries in the store, one for csv1 and another for csv2. Upon swapping you load the selectedRows from whichever one is selected in the drop down.

Something like this might work:

iimport dash
from dash import dcc, html, Input, Output, State, Patch, no_update
import dash_ag_grid as dag
import pandas as pd

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(['Table 1', 'Table 2'], 'NYC', id='dropdown'),

    html.Div(id="grid_div"),

    dcc.Store(id="selected", storage_type='local')
])


@app.callback(
    Output('grid', 'children', allow_duplicate=True),
    Input('dropdown', 'value'),
    prevent_initial_call=True

)
def clear_output(value):
    if value:
        return []


@app.callback(
    Output('grid_div', 'children'),
    Input('dropdown', 'value'),
    State("selected", "data"),
    prevent_initial_call=True

)
def read_1(value, selections):
    if value == "Table 1":
        df = pd.read_csv('table1.csv')
        key = 'table1'
    elif value == "Table 2":
        df = pd.read_csv('table2.csv')
        key = 'table2'
    else:
        return "Something went wrong"

    column_defs = []
    for col_index, col_name in enumerate(df.columns):
        column_defs.append(
            {
                "headerName": f"{col_name}",
                "field": f"{col_name}",
                "width": 500,
                "resizable": False,
                "checkboxSelection": True if col_index == 0 else False,
                "filter": True,
            }
        )

    grid = dag.AgGrid(
        id="grid",
        className="ag-theme-alpine border",
        rowData=df.to_dict("records"),
        columnDefs=column_defs,
        columnSize="sizeToFit",
        selectedRows=selections.get(key),
        dashGridOptions={
            "domLayout": "autoHeight",
            "columnHoverHighlight": True,
            "rowSelection": "multiple",
        },
        style={"height": "100%", "fontSize": "20px"},
    )
    return grid


@app.callback(
    Output("selected", "data"),
    Input("grid", "selectedRows"),
    Input('dropdown', 'value'),
    prevent_initial_call=True
)
def store(selections, value):
    if value == "Table 1":
        key = 'table1'
    elif value == "Table 2":
        key = 'table2'
    if key:
        select_store = Patch()
        select_store[key] = selections
        return select_store
    return no_update


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

Thank you @jinnyzor

1 Like