Dash AG Grid: Using the same grid id in a dynamic page

Hello all,

This issue and solution pertains to when you have the same page loading the same grid id between pages. (Variable pages loading stock info) In which you do not want to persist the column interactions between the two.

The key is to pass either a columnState or resetColumnState=True in the grid that you want to reset. Also note, the columnState cannot be [] like in another method to take the columnDefs mentioned here:

Here is an example:

import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State
import dash_bootstrap_components as dbc
import pandas as pd
import yfinance as yf
import dash

app = Dash(__name__, external_stylesheets=[dbc.themes.DARKLY],
           meta_tags=[{'http-equiv': 'content-security-policy',
                       'content': "default-src 'self'; script-src 'self' 'unsafe-inline';"
                                  " style-src https://* 'self' 'unsafe-inline'; "
                                  "font-src data: https://* 'self' 'unsafe-inline';"
                                  "img-src data: https://* 'self'"}],
            use_pages=True, pages_folder=''
           )

equities = {
    "AAPL": "Apple",
    "MSFT": "Microsoft",
    "AMZN": "Amazon",
    "GOOGL": "Alphabet",
    "TSLA": "Tesla",
    "BRK-B": "Berkshire Hathaway",
    "UNH": "United Health Group",
    "JNJ": "Johnson & Johnson",
}


def get_stock_data():
    return yf.download(tickers=list(equities.keys()), period="2y", group_by="ticker")


stock_data = get_stock_data()


def last_close(ticker):
    return stock_data[ticker]["Close"].iloc[-1]


data = {
    "ticker": [ticker for ticker in equities],
    "company": [name for name in equities.values()],
    "quantity": [75, 40, 100, 50, 40, 60, 20, 40],
    "price": [last_close(ticker) for ticker in equities],
}
df = pd.DataFrame(data)

columnDefs = [
    {
        "headerName": "Stock Ticker",
        "field": "ticker",
        "type": "textAligned",
        "filter": True
    },
    {
        "headerName": "Company",
        "field": "company",
        "type": "textAligned",
        "filter": True
    },
    {
        "headerName": "Shares",
        "field": "quantity",
        "editable": True,
    },
    {
        "headerName": "Last Close Price",
        "field": "price",
        "cellRenderer": "agAnimateShowChangeCellRenderer",
    },
]


defaultColDef = {
    "type": ["rightAligned"],
    "filter": "agNumberColumnFilter",
    "resizable": True,
    "sortable": True,
    "editable": False,
    "floatingFilter": True,
}

table = dag.AgGrid(
    id="portfolio-grid",
    className="ag-theme-alpine-dark",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
    columnSize=None,
    defaultColDef=defaultColDef,
    dashGridOptions={'undoRedoCellEditing':True, 'undoRedoCellEditingLimit': 20, "rowSelection":"single",},
    getRowStyle={
                "styleConditions": [
                    {"condition": "data.quantity > 50", "style": {"color": "orange"}},
                ]
            },
    columnState=[{'colId': 'ticker', 'pinned':False}, {'colId': 'company', 'pinned':False},
                 {'colId': 'quantity', 'pinned':False}, {'colId':'price', 'pinned':False}],
    # resetColumnState=True
)

header = html.Div("My Portfolio", className="h2 p-2 text-white bg-primary text-center")

dash.register_page('Home', path='/', layout=table)
dash.register_page('1', layout=table)
dash.register_page('2', layout=table)
dash.register_page('3', layout=table)

app.layout = dbc.Container(
    [
        header,
        dbc.Nav([dbc.NavLink(pg['name'], href=pg['path']) for pg in dash.page_registry.values()]),
        dbc.Row(dbc.Col(dash.page_container, className="py-4")),
    ],
)

if __name__ == "__main__":
    app.run_server(debug=True, port=12345)
1 Like