Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/components_page/components/__tests__/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def rename_variable(snippet_path, suffix, variable, assign_op="="):
for line in lines:
if line.startswith(f"{variable} {assign_op}"):
line = line.replace(
f"{variable} {assign_op}", f"{variable}_{suffix} {assign_op}"
f"{variable} {assign_op}", f"{variable}__{suffix} {assign_op}"
)
new_lines.append(line)

Expand Down
57 changes: 57 additions & 0 deletions docs/components_page/components/__tests__/test_modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,60 @@ def check_modal_centered_callbacks(runner):
lambda: len(runner.find_elements(".modal-content")) == 0,
timeout=4,
)


# ------------------------------


def test_r_modal_toggle(dashr):
r_app = load_r_app((HERE.parent / "modal" / "toggle.R"), "modal")
dashr.start_server(r_app)
check_modal_toggle_callbacks(dashr)


def test_jl_modal_toggle(dashjl):
jl_app = load_jl_app((HERE.parent / "modal" / "toggle.jl"), "modal")
dashjl.start_server(jl_app)
check_modal_toggle_callbacks(dashjl)


def check_modal_toggle_callbacks(runner):
runner.find_element("#open-toggle-modal").click()
wait.until(
lambda: len(runner.find_elements(".modal-content")) != 0,
timeout=4,
)
wait.until(
lambda: len(runner.find_elements("#toggle-modal-1")) == 1,
timeout=4,
)
wait.until(
lambda: len(runner.find_elements("#toggle-modal-2")) == 0,
timeout=4,
)

runner.find_element("#open-toggle-modal-2").click()
wait.until(
lambda: len(runner.find_elements("#toggle-modal-2")) == 1,
timeout=4,
)
wait.until(
lambda: len(runner.find_elements("#toggle-modal-1")) == 0,
timeout=4,
)

runner.find_element("#open-toggle-modal-1").click()
wait.until(
lambda: len(runner.find_elements("#toggle-modal-1")) == 1,
timeout=4,
)
wait.until(
lambda: len(runner.find_elements("#toggle-modal-2")) == 0,
timeout=4,
)

runner.find_elements(".modal-header > .btn-close")[0].click()
wait.until(
lambda: len(runner.find_elements(".modal-content")) == 0,
timeout=4,
)
5 changes: 3 additions & 2 deletions docs/components_page/components/__tests__/test_snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_r_snippets(dash_thread_server, dashr_server, config):
r_snippet = rename_variable(
r_snippet_path, i, name, assign_op="<-"
)
python_r_compare.append((py_snippet, r_snippet, f"{name}_{i}"))
python_r_compare.append((py_snippet, r_snippet, f"{name}__{i}"))

if python_r_compare:
assert_layouts_equal(
Expand Down Expand Up @@ -106,7 +106,7 @@ def test_jl_snippets(dash_thread_server, dashjl_server, config):

if jl_snippet_path.exists():
jl_snippet = rename_variable(jl_snippet_path, i, name)
python_jl_compare.append((py_snippet, jl_snippet, f"{name}_{i}"))
python_jl_compare.append((py_snippet, jl_snippet, f"{name}__{i}"))

if python_jl_compare:
assert_layouts_equal(
Expand All @@ -123,6 +123,7 @@ def test_jl_snippets(dash_thread_server, dashjl_server, config):
def assert_layouts_equal(
compare, runner, wrapper, port, py_runner, py_env, py_port
):

# Get python snippet layout
app = py_source_to_app(
PY_WRAPPER.format(
Expand Down
6 changes: 6 additions & 0 deletions docs/components_page/components/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ To vertically center the modal on the page, set `centered=True`.

{{example:components/modal/centered.py:modal}}

## Toggle between modals

With some clever use of callbacks, you can also create modals that open other modals.

{{example:components/modal/toggle.py:modal}}

{{apidoc:src/components/modal/Modal.js}}

{{apidoc:src/components/modal/ModalHeader.js}}
Expand Down
76 changes: 76 additions & 0 deletions docs/components_page/components/modal/toggle.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
library(dashBootstrapComponents)
library(dashHtmlComponents)

modal_1 <- dbcModal(
list(
dbcModalHeader(dbcModalTitle("Modal 1")),
dbcModalBody("This is the content of the first modal"),
dbcModalFooter(
dbcButton(
"Open Modal 2",
id = "open-toggle-modal-2",
class_name = "ms-auto",
n_clicks = 0
)
)
),
id = "toggle-modal-1",
is_open = FALSE
)

modal_2 <- dbcModal(
list(
dbcModalHeader(dbcModalTitle("Modal 2")),
dbcModalBody("This is the second modal"),
dbcModalFooter(
dbcButton(
"Back to Modal 1",
id = "open-toggle-modal-1",
class_name = "ms-auto",
n_clicks = 0
)
)
),
id = "toggle-modal-2",
is_open = FALSE
)


modal <- htmlDiv(
list(
dbcButton("Open modal", id = "open-toggle-modal", n_clicks = 0),
modal_1,
modal_2
)
)

app$callback(
output("toggle-modal-1", "is_open"),
list(
input("open-toggle-modal", "n_clicks"),
input("open-toggle-modal-1", "n_clicks"),
input("open-toggle-modal-2", "n_clicks"),
state("toggle-modal-1", "is_open")
),
function(n0, n1, n2, is_open) {
if (n0 > 0 | n1 > 0 | n2 > 0) {
return(!is_open)
}
return(is_open)
}
)

app$callback(
output("toggle-modal-2", "is_open"),
list(
input("open-toggle-modal-2", "n_clicks"),
input("open-toggle-modal-1", "n_clicks"),
state("toggle-modal-2", "is_open")
),
function(n2, n1, is_open) {
if (n1 > 0 | n2 > 0) {
return(!is_open)
}
return(is_open)
}
)
63 changes: 63 additions & 0 deletions docs/components_page/components/modal/toggle.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using DashBootstrapComponents, DashHtmlComponents

modal_1 = dbc_modal(
[
dbc_modalheader(dbc_modaltitle("Modal 1")),
dbc_modalbody("This is the content of the first modal"),
dbc_modalfooter(
dbc_button(
"Open Modal 2",
id = "open-toggle-modal-2",
class_name = "ms-auto",
n_clicks = 0,
),
),
],
id = "toggle-modal-1",
is_open = false,
)

modal_2 = dbc_modal(
[
dbc_modalheader(dbc_modaltitle("Modal 2")),
dbc_modalbody("This is the second modal"),
dbc_modalfooter(
dbc_button(
"Back to Modal 1",
id = "open-toggle-modal-1",
class_name = "ms-auto",
n_clicks = 0,
),
),
],
id = "toggle-modal-2",
is_open = false,
)


modal = html_div([
dbc_button("Open modal", id = "open-toggle-modal", n_clicks = 0),
modal_1,
modal_2,
])

callback!(
app,
Output("toggle-modal-1", "is_open"),
Input("open-toggle-modal", "n_clicks"),
Input("open-toggle-modal-1", "n_clicks"),
Input("open-toggle-modal-2", "n_clicks"),
State("toggle-modal-1", "is_open"),
) do n0, n1, n2, is_open
return n0 > 0 || n1 > 0 || n2 > 0 ? is_open == 0 : is_open
end;

callback!(
app,
Output("toggle-modal-2", "is_open"),
Input("open-toggle-modal-2", "n_clicks"),
Input("open-toggle-modal-1", "n_clicks"),
State("toggle-modal-2", "is_open"),
) do n2, n1, is_open
return n1 > 0 || n2 > 0 ? is_open == 0 : is_open
end;
75 changes: 75 additions & 0 deletions docs/components_page/components/modal/toggle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import dash_bootstrap_components as dbc
import dash_html_components as html
from dash.dependencies import Input, Output, State

modal_1 = dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Modal 1")),
dbc.ModalBody("This is the content of the first modal"),
dbc.ModalFooter(
dbc.Button(
"Open Modal 2",
id="open-toggle-modal-2",
class_name="ms-auto",
n_clicks=0,
)
),
],
id="toggle-modal-1",
is_open=False,
)

modal_2 = dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Modal 2")),
dbc.ModalBody("This is the second modal"),
dbc.ModalFooter(
dbc.Button(
"Back to Modal 1",
id="open-toggle-modal-1",
class_name="ms-auto",
n_clicks=0,
)
),
],
id="toggle-modal-2",
is_open=False,
)


modal = html.Div(
[
dbc.Button("Open modal", id="open-toggle-modal", n_clicks=0),
modal_1,
modal_2,
]
)


@app.callback(
Output("toggle-modal-1", "is_open"),
[
Input("open-toggle-modal", "n_clicks"),
Input("open-toggle-modal-1", "n_clicks"),
Input("open-toggle-modal-2", "n_clicks"),
],
[State("toggle-modal-1", "is_open")],
)
def toggle_modal_1(n0, n1, n2, is_open):
if n0 or n1 or n2:
return not is_open
return is_open


@app.callback(
Output("toggle-modal-2", "is_open"),
[
Input("open-toggle-modal-2", "n_clicks"),
Input("open-toggle-modal-1", "n_clicks"),
],
[State("toggle-modal-2", "is_open")],
)
def toggle_modal_2(n2, n1, is_open):
if n1 or n2:
return not is_open
return is_open
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ exclude =
docs/components_page/components/modal/scrollable_source.py
docs/components_page/components/modal/simple.py
docs/components_page/components/modal/size.py
docs/components_page/components/modal/toggle.py
docs/components_page/components/nav/navlink.py,
docs/components_page/components/navbar/navbar.py,
docs/components_page/components/offcanvas/backdrop.py,
Expand Down