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

Change parent from module with express #1841

Open
julibeg opened this issue Feb 5, 2025 · 0 comments
Open

Change parent from module with express #1841

julibeg opened this issue Feb 5, 2025 · 0 comments

Comments

@julibeg
Copy link

julibeg commented Feb 5, 2025

I would like to update a navset_bar from within modules in my Express app, but I can't seem to get it to work. The MWEs below have a navbar with several panels and I want each subsequent panel to contain a button that takes us back to the first panel. This works in Panel 2 (which is not a module), but does not work in the other panels (which are a module)

Naively, I tried

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

ui.page_opts(title="Navset MWE", full_width=True, id="page")


@module
def other_panels(input, output, session, label):
    with ui.nav_panel(label):
        ui.input_action_button(
            "module_button", "Go back to Panel 1", cls="btn btn-primary"
        )

    @reactive.effect
    @reactive.event(input.module_button)
    def _():
        ui.update_navs("navbar", "Panel 1")


with ui.navset_bar(id="navbar", title=None):

    with ui.nav_panel("Panel 1"):
        ui.tags.p("hi")
    with ui.nav_panel("Panel 2"):
        ui.input_action_button(
            "back_to_1_from_p2", "Go back to Panel 1", cls="btn btn-primary"
        )
    other_panels("p3", label="Panel 3")
    other_panels("p4", label="Panel 4")


@reactive.effect
@reactive.event(input.back_to_1_from_p2)
def _():
    ui.update_navs("navbar", "Panel 1")

I assumed the parent namespace to be '' and thus the id "navbar" to be valid within the module as well, but looks like this is not the case.

I then tried to get it working by passing a callback, but no luck

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

ui.page_opts(title="Navset MWE", full_width=True, id="page")


@module
def other_panels(input, output, session, label, callback):
    with ui.nav_panel(label):
        ui.input_action_button(
            "module_button", "Go back to Panel 1", cls="btn btn-primary"
        )

    @reactive.effect
    @reactive.event(input.module_button)
    def _():
        callback()


# put update into function that we can pass as a callback
def go_to_p1():
    print("going back to Panel 1")
    ui.update_navs("navbar", "Panel 1")


with ui.navset_bar(id="navbar", title=None):

    with ui.nav_panel("Panel 1"):
        ui.tags.p("hi")
    with ui.nav_panel("Panel 2"):
        ui.input_action_button(
            "back_to_1_from_p2", "Go back to Panel 1", cls="btn btn-primary"
        )
    other_panels("p3", label="Panel 3", callback=go_to_p1)
    other_panels("p4", label="Panel 4", callback=go_to_p1)


@reactive.effect
@reactive.event(input.back_to_1_from_p2)
def _():
    go_to_p1()

I've seen similar examples that work (e.g. #690), but they all use Core syntax and I couldn't get it working with Express. Any pointers are highly appreciated!

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

No branches or pull requests

1 participant