from dash import dcc, html, no_update, Dash, Output, Input, State, page_container, ALL, ctx
import dash
import dash_bootstrap_components as dbc
from dash_bootstrap_templates import load_figure_template
app = Dash(__name__, use_pages=True,
external_stylesheets=[dbc.themes.LITERA])
load_figure_template("bootstrap")
app.layout = html.Div([
html.Div(dcc.Link('Home', href='/')),
html.Div(dcc.Link('Stocks', href='/stocks')),
html.Div(dcc.Store(id='storeStock')),
page_container]
)
stockList = ['META', 'AAPL', 'AMZN', 'NFLX', 'GOOG', 'TSLA']
def layout_home():
layout = html.Table([
html.Tbody([
html.Tr([html.Td(
dcc.Link(sym, href='/stocks'),
# dbc.Button(sym, href='/stocks', color='dark', className='text-white'),
id={'index': sym, 'type': 'stock'}, n_clicks=0)]) for sym in stockList])
])
return layout
def layout_stocks():
layout = html.Div([
html.H4('Stocks'),
html.Div(dcc.Dropdown(id=f'dds_stock',
options=stockList,
persistence=True,
persistence_type='session',
style={'width': '100px'})),
html.Div(id='hidden_stock_trigger'),
html.Div(id='selected_stock')
])
return layout
app.clientside_callback(
"""
function (i) {
if (i.reduce((a, b) => a + b, 0) > 0) {
stock = JSON.parse(dash_clientside.callback_context.triggered[0].prop_id.split('.n_clicks')[0]).index
return stock
}
return ''
}
""",
Output('storeStock', 'data'),
Input({'index': ALL, 'type': 'stock'}, 'n_clicks'),
Prevent_Inital_Call=True
)
dash.register_page('Home', path='/', layout=layout_home())
dash.register_page('Stock Details', path='/stocks', layout=layout_stocks())
@app.callback(
Output('selected_stock', 'children'),
Input('dds_stock', 'value'),
)
def selected_stock(stock):
print(f'selected_stock({stock})')
return stock
# @app.callback(
# Output('dds_stock', 'value'),
# Input('hidden_stock_trigger', 'n_clicks'),
# State('storeStock', 'data')
# )
# def stored_stock(v, stock):
# print(f'stored_stock({stock})')
# return stock
if __name__ == '__main__':
app.run(debug=True)
I have the problem demonstrated in the code listed above. Note that I improved your solution so that the selected stock is not simply printed on the page, but loads the dropdown menu which essentially constitutes that the stock is selected for the rest of the page to work.
In the example above, persistence is working just fine if you go back and forth from the home page to the stock page, but the home to stock linking doesn’t operate. After uncommenting the stored_stock
callback, the linking works but persistence is gone when you travel to the Home page and back. You will also see it firing empty selected_stock
calls on the page changes that clear the dropdown value.
Please let me know if you can find the right modification so the stored_stock
isn’t clearing things. I would like it if your callback and selected_stock set storeStock
, but then you get a duplicate output callbacks error.