Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui.modal_remove() requires ui.modal_show() #1812

Open
gadenbuie opened this issue Jan 3, 2025 · 2 comments
Open

ui.modal_remove() requires ui.modal_show() #1812

gadenbuie opened this issue Jan 3, 2025 · 2 comments

Comments

@gadenbuie
Copy link
Collaborator

Originally posted by @schloerke in #1810

Similarly, I can only hide the modal if it is programmatically shown.

What I'd like to have work: Shinylive App

from shiny.express import input, render, ui
from shiny import reactive


modal = ui.modal(ui.input_slider("n", "N", 0, 100, 20), footer = ui.input_action_button("close_btn", "Close modal"), easy_close=False)

modal

@reactive.effect
@reactive.event(input.close_btn)
def _():
    print("Start remove modal")
    ui.modal_remove()
    print("End   remove modal")

What does work: Shinylive App

from shiny.express import input, render, ui
from shiny import reactive


modal = ui.modal(ui.input_slider("n", "N", 0, 100, 20), footer = ui.input_action_button("close_btn", "Close modal"), easy_close=False)

@reactive.effect
def _():
    ui.modal_show(modal)

@reactive.effect
@reactive.event(input.close_btn)
def _():
    print("Start remove modal")
    ui.modal_remove()
    print("End   remove modal")

If the modal is already open, why am I required to programmatically open it to close it.

@gadenbuie
Copy link
Collaborator Author

gadenbuie commented Jan 3, 2025

If the modal is already open, why am I required to programmatically open it to close it.

The short answer is that ui.modal_show() puts the modal UI inside a set of wrapper containers where ui.modal_remove() expects to find and remove it. If you just add the modal UI to the app UI, the modal isn't where ui.modal_remove() expects to find it.

You can get close by replicating the expected markup but even if you do that, you'll be missing out on event listeners that are set up by ui.modal_show().

I think Shiny Express makes the approach you tried (of just showing modal directly in the UI) more appealing, but in Shiny Core and in Shiny for R using an observe(showModal(init_modal)) is a common pattern and it seems less tempting to just add the modal UI directly into the app.

@gadenbuie
Copy link
Collaborator Author

On the other hand, you make a great point and if we turned the modal into a custom element the pattern you described would be quite natural.

That said, another reason to use ui.modal_show() over render.ui() or similar is that ui.modal_show() and ui.modal_remove() can show and hide the modal within a reactive cycle, whereas using render.ui() would have to change state once per reactive cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant