pythonpy-shiny

Python Shiny: How to toggle visibility of a conditional panel with two buttons?


Python Shiny: Open and close panel_conditional through button press

In my webapplication I want to open a conditional panel through a button click. On that panel I want to add a close button to close it again. Below I will add some codesnippets on what I have tried:

First I tried this:

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show"),
    ui.panel_conditional(
        "input.show",
        ui.input_slider("slider", None, min=0, max=100, value=50),
        ui.input_action_button("close", "Close")
    ),
)


def server(input: Inputs, output: Outputs, session: Session):
    pass


app = App(app_ui, server)

With this method I can open the panel but not close it again. This makes sense because the close button does not have a function yet.

Second attempt:

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show"),
    ui.panel_conditional(
        "close_panel",
        ui.input_slider("slider", None, min=0, max=100, value=50),
        ui.input_action_button("close", "Close")
    ),
)


def server(input: Inputs, output: Outputs, session: Session):
    @reactive.Effect
    def close_panel():
        value = False

        if input.show():
            value = False
        if input.close():
            value = True

        return value


app = App(app_ui, server)

Does somebody know a way how to open and close the panel by using two buttons? Thank you in advance :).


Solution

    1. Your panel_conditional has the wrong condition input value dependent on another ui such as you ui.input_action_button labeled with id=show. You can grab input.show to let those two UI features be linked to each other
    2. The way the ui.input_action_button works is that it is a counter that starts at 0 and each click iterates the counter by 1. For example the value of the input.close will start at 0 and every click will increment it by 1; Normally, the person using the UI would click on open first and then close so the value of open should always be greater than the value of close and if it is not, then it will fail the condition
    3. The value in your def server() does not use that value in your UI. To use it, you will require a UI element that has an ui.update_____ type of function such as ui.update_action_button or so
    4. This solution does not take into account the edge case that the person may click on the show button more than once, in which case will require the person to click on the close button an equal number of times
    5. To view the output of input.show and input.close for better understanding, put this into the def server():

    .

    @reactive.Effect 
    def _():
        print(input.show(), input.close())
    

    Here is the solution:

    app_ui = ui.page_fluid(
        ui.input_action_button("show", "Show"),
        ui.panel_conditional(
            "input.show > input.close",
            ui.input_slider("slider", None, min=0, max=100, value=50),
            ui.input_action_button("close", "Close")
        ), )
    
    
    def server(input, output, session):
        pass
    
    
    app = App(app_ui, server)