I have a conditional input that I want present in the sidebar panel only when a previous input has a certain value. Unlike when using conditionalPanel()
and if i use if
statements, the conditional input is created with renderUI()
and displayed accordingly when the condition is met. However, when the condition is no longer met, the conditional input does not disappear even if the code for the such input is inside observe()
. Here is a minimal example:
library(shiny)
ui <- fluidPage(
# Application title
titlePanel("Conditional input"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "input1",
label = "Input1",
choices = c("A","B"),
selected = "A"),
uiOutput(outputId = "input2")
),
mainPanel()
)
)
server <- function(input, output){
observe(
if(input$input1 == "B"){
output$input2 = renderUI({
selectInput(inputId = "input2",
label = "Input2",
choices = c("option1",
"option2"))
})
}
)
}
shinyApp(ui = ui, server = server)
Initially:
With the appropiate choice in input1, the conditional input2 shows up:
However, when going back to choice in input1 that no longer meets the condition needed to have input2, such input2 remains displayed:
As mentioned above, when using conditionalPanel()
the conditional input appears/disappears as expected, but is it possible to make it work also as shown in the minimal example with some small modification?
Thanks!
Here's a simple solution that gives you what you want.
library(shiny)
ui <- fluidPage(
titlePanel("Conditional input"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "input1",
label = "Input1",
choices = c("A","B"),
selected = "A"
),
uiOutput(outputId = "uiPanel")
),
mainPanel()
)
)
server <- function(input, output){
output$uiPanel <- renderUI({
if (input$input1 == "B") {
selectInput(inputId = "input2",
label = "Input2",
choices = c("option1", "option2")
)
}
})
}
shinyApp(ui = ui, server = server)
The renderUI
returns NULL
if input$input1 == "A"
. Note that I've renamed the uiOutput
to avoid the clash of IDs and refactored the code to remove the redundant call to observe()
. This isn't necessary because the reference to input$input1
inside the renderUI
call is all that's necessary to trigger a call whenever needed.