I’m not sure, where the inputs are defined, in the modal itself as dcc.Input()
or elsewhere. Here is an example (adapted from here) on how to do different things if clicking OK or CANCEL within the modal.
import dash_bootstrap_components as dbc
from dash import Input, Output, State, html, dcc, ctx
import dash
import plotly.express as px
import numpy as np
# design of the modal
modal = html.Div(
[
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Header"), close_button=False),
# ^^ don't show an "X" to close the modal
dbc.ModalBody("By click on cancel, the figure is going to be reset"),
dbc.ModalFooter(
children=[
dbc.ButtonGroup(
[
dbc.Button(
"OK",
id="ok",
className="m-1",
n_clicks=0
),
dbc.Button(
"Cancel",
id="cancel",
className="m-1",
n_clicks=0
)
]
)
]
),
],
id="modal",
is_open=False,
centered=True,
keyboard=False,
backdrop="static",
# ^^ don't accept keyboard interaction to close the modal (ESC)
),
]
)
app = dash.Dash(
__name__,
external_stylesheets=[dbc.themes.CYBORG],
meta_tags=[
{'name': 'viewport',
'content': 'width=device-width, initial-scale=1.0'
}
]
)
app.layout = html.Div(
[
dbc.Button(
"open modal",
id="open",
n_clicks=0
),
dcc.Graph(
id='graph',
figure=px.imshow(np.random.randint(0, 255, size=(10, 10)))
),
modal
]
)
@app.callback(
Output("modal", "is_open"),
Output("graph", "figure"),
Input("open", "n_clicks"),
Input("ok", "n_clicks"),
Input("cancel", "n_clicks"),
State("graph", "figure"),
State("modal", "is_open"),
prevent_initial_call=True
)
def toggle_modal(open_modal, ok, cancel, current_figure, is_open):
# which button triggered the callback?
trigger = ctx.triggered_id
# open modal has been clicked --> just open the modal and return current figure
if trigger == 'open':
return not is_open, current_figure
# ok button has been clicked --> create new figure
if trigger == 'ok':
new_figure = px.imshow(np.random.randint(0, 255, size=(10, 50)))
return not is_open, new_figure
# cancel button has been clicked --> reset the figure
if trigger == 'cancel':
return not is_open, {}
if __name__ == '__main__':
app.run(debug=True, port=8051)