Hello all,
Not sure if this will help anyone, but I thought it was pretty cool and helps with my design.
This app’s design uses both Dash’s pages registry and the url pathname for custom function returns.
from dash import dcc, html, no_update, Dash, Output, Input, State, page_container, ALL, ctx
import dash
app = Dash(__name__, use_pages=True, pages_folder='')
app.layout = html.Div(
[
dcc.Location(id='url'),
dcc.Link('Home', href='/'),
html.Br(),
dcc.Link('My Custom Layout', href='/myCustomLayout/testing'),
html.Br(),
html.Br(),
dcc.Store(id='selectedStock'),
page_container,
html.Div(id='page-content')]
)
stockList = ['META', 'AAPL', 'AMZN', 'NFLX', 'GOOG', 'TSLA']
def myCustomLayout(v):
return html.Div(v)
def stocks():
layout = html.Table([
html.Tbody([
html.Tr([html.Td(dcc.Link(i, href='/stocks'), id={'index':i, 'type':'stock'}, n_clicks=0)]) for i in stockList
])
])
return layout
app.clientside_callback(
"""
function (i, d) {
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 d
}
""",
Output('selectedStock', 'data'),
Input({'index':ALL, 'type':'stock'}, 'n_clicks'),
State('selectedStock','data'),
prevent_initial_call=True
)
dash.register_page('Home', path='/', layout=stocks())
dash.register_page('Stock Details', path='/stocks', layout=html.Div([html.Div(id='hiddenTrigger'),
html.Div(id='stockInfo')]))
@app.callback(
Output('page-content', 'children'),
Output('_pages_content','style'),
Input('url', 'pathname')
)
def caterPage(path):
if 'myCustomLayout' in path:
return myCustomLayout(path.split('/myCustomLayout/')[1]), {'display':'none'}
else:
return '', {'display':'initial'}
@app.callback(
Output('stockInfo', 'children'),
Input('hiddenTrigger','n_clicks'),
State('selectedStock','data')
)
def caterStock(v, s):
return s
if __name__ == '__main__':
app.run(debug=True)
Why it works.
The callback that determines which routing returns a display argument to the ‘_pages_content’ (the default container for pages) which either hides or shows the content depending whether or not a custom function is run.