Thanks @chriddyp – this solution worked successfully for me, with the important addition of the suppression statement app.config['suppress_callback_exceptions'] = True
(see Chris’ response to this thread: dcc.Tabs: Filling tabs with dynamic content. How to organize the callbacks?)
Given this solution, I don’t see why anyone would want to use dcc.tabs
Method #2 ( Content as Tab Children) – it basically makes it impossible to have any dynamic content in your tabbed app. That will be a dealbreaker for most of us, I think.
Anyway, here is my updated code, with Chris’ solution applied, in case others have the same problem.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
app = dash.Dash()
app.config['suppress_callback_exceptions'] = True
app.layout = html.Div([
dcc.Tabs(id="tabs", value='tab-1', children=[
dcc.Tab(label='Tab one', value='tab-1'),
dcc.Tab(label='Tab two', value='tab-2'),
]),
html.Div(id='tabs-content')
])
@app.callback(Output('tabs-content', 'children'),
[Input('tabs', 'value')])
def render_content(tab):
if tab == 'tab-1':
return html.Div([
html.H3('Type any response in the box:'),
dcc.Input(
id='number-in',
value=1,
style={'fontSize':20}
),
html.Button(
id='submit-button',
n_clicks=0,
children='Submit',
style={'fontSize':20}
),
html.H4(id="response_div"),
],
className='twelve columns')
elif tab == 'tab-2':
return html.Div([
html.H3('Tab content 2')
])
# Call back number
@app.callback(
Output('response_div', 'children'),
[Input('submit-button', 'n_clicks')],
[State('number-in', 'value')])
def output(n_clicks, number):
return 'The response you have picked is: {}'.format(number),
if __name__ == '__main__':
app.run_server(debug=True)