-
Notifications
You must be signed in to change notification settings - Fork 225
Description
Describe your context
We have a fairly complex app which was wonderfully working on Dash 1.4.0 and before. Now I updated to Dash 1.5.0 and subsequently to 1.5.1 and the fact of including a DataTable makes all callbacks not working anymore (even the clientside ones).
I managed to break it down to a minimal working example which exposes the error:
This does work (i.e. clicking on one of the "Settings" Buttons make a modal appear:
import dash
import dash_html_components as html
from dash import no_update
import dash_table as dt
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
NODE_SETTINGS_MODAL_PREFIX = 'test'
FIELD_SETTINGS = 'field-settings'
FS_OPTIONS = 'options'
app = dash.Dash(__name__)
def layout() -> html.Div:
div1 = html.Div(children=[
html.Span('Node 1', id=f'label-{1}'),
html.Button('Settings', id=f'settings-{1}'),
])
div2 = html.Div(children=[
html.Span('Node 2', id=f'label-{2}'),
html.Button('Settings', id=f'settings-{2}'),
])
layout = html.Div([
build_node_settings_modal(),
div1,
div2
])
return layout
def build_node_settings_modal() -> dbc.Modal:
return dbc.Modal(
[
dbc.ModalHeader(html.Div([
"Settings",
dbc.Button(id=f"{NODE_SETTINGS_MODAL_PREFIX}-close", className="modal-close-button fas fa-times")
])),
dbc.ModalBody([
html.Div(id=f'{NODE_SETTINGS_MODAL_PREFIX}-settings', children=[
# dt.DataTable(
# id=f'{FIELD_SETTINGS}-{FS_OPTIONS}',
# columns=[{"name": i, "id": i} for i in ['value', 'label']],
# data=[{'value': 'Value 1', 'label': 'Item 1'}]
# ),
])
]),
], id=NODE_SETTINGS_MODAL_PREFIX,
)
app.layout = layout
@app.callback(
[Output(NODE_SETTINGS_MODAL_PREFIX, "is_open"),
Output(NODE_SETTINGS_MODAL_PREFIX, "className")], # not a genius thing to abuse the className
[Input(f"{NODE_SETTINGS_MODAL_PREFIX}-close", "n_clicks"),
*[Input(f'settings-{i}', 'n_clicks') for i in [1, 2]],
]
)
def toggle_node_settings_modal(*args):
if all(a is None for a in args):
return no_update, no_update
ctx = dash.callback_context
triggered = ctx.triggered[0]
if triggered['prop_id'] == f'{NODE_SETTINGS_MODAL_PREFIX}-close.n_clicks': # Force close on Escape, close button and click beside the modal
return False, ""
node_id = triggered['prop_id'].split('.')[0].split('-')[1]
return True, node_id
if __name__ == '__main__':
app.run_server(debug=True)
When I uncomment the dash_table part:
import dash
import dash_html_components as html
from dash import no_update
import dash_table as dt
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
NODE_SETTINGS_MODAL_PREFIX = 'test'
FIELD_SETTINGS = 'field-settings'
FS_OPTIONS = 'options'
app = dash.Dash(__name__)
def layout() -> html.Div:
div1 = html.Div(children=[
html.Span('Node 1', id=f'label-{1}'),
html.Button('Settings', id=f'settings-{1}'),
])
div2 = html.Div(children=[
html.Span('Node 2', id=f'label-{2}'),
html.Button('Settings', id=f'settings-{2}'),
])
layout = html.Div([
build_node_settings_modal(),
div1,
div2
])
return layout
def build_node_settings_modal() -> dbc.Modal:
return dbc.Modal(
[
dbc.ModalHeader(html.Div([
"Settings",
dbc.Button(id=f"{NODE_SETTINGS_MODAL_PREFIX}-close", className="modal-close-button fas fa-times")
])),
dbc.ModalBody([
html.Div(id=f'{NODE_SETTINGS_MODAL_PREFIX}-settings', children=[
dt.DataTable(
id=f'{FIELD_SETTINGS}-{FS_OPTIONS}',
columns=[{"name": i, "id": i} for i in ['value', 'label']],
data=[{'value': 'Value 1', 'label': 'Item 1'}]
),
])
]),
], id=NODE_SETTINGS_MODAL_PREFIX,
)
app.layout = layout
@app.callback(
[Output(NODE_SETTINGS_MODAL_PREFIX, "is_open"),
Output(NODE_SETTINGS_MODAL_PREFIX, "className")], # not a genius thing to abuse the className
[Input(f"{NODE_SETTINGS_MODAL_PREFIX}-close", "n_clicks"),
*[Input(f'settings-{i}', 'n_clicks') for i in [1, 2]],
]
)
def toggle_node_settings_modal(*args):
if all(a is None for a in args):
return no_update, no_update
ctx = dash.callback_context
triggered = ctx.triggered[0]
if triggered['prop_id'] == f'{NODE_SETTINGS_MODAL_PREFIX}-close.n_clicks': # Force close on Escape, close button and click beside the modal
return False, ""
node_id = triggered['prop_id'].split('.')[0].split('-')[1]
return True, node_id
if __name__ == '__main__':
app.run_server(debug=True)
The callback won't fire anymore (and there is not even a callback related to the table!)
So no modal showing up
- replace the result of
pip list | grep dash
below
dash 1.5.1
dash-bootstrap-components 0.7.2
dash-canvas 0.0.11
dash-core-components 1.4.0
dash-cytoscape 0.1.1
dash-html-components 1.0.1
dash-renderer 1.2.0
dash-table 4.5.0
-
if frontend related, tell us your Browser, Version and OS
- OS: OSX
- Browser Chrome, Vivaldi, Safari
Describe the bug
Having a DataTable in the layout breaks all callbacks, i.e callbacks are not firing at all anymore
Uncommenting the use of DataTable makes everything OK
Expected behavior
Callback working