Home > Software engineering >  Display `sliderInput` only if radio button is selected
Display `sliderInput` only if radio button is selected

Time:09-15

I would like to display a slider (in below example, bins) in the sidepanel only if a certain radio button is selected (in below example, y).

library(shiny)
ui <- fluidPage(
  
  
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      width = 3, 
      radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),

      # display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)),
    
    mainPanel(
      
      plotOutput("distPlot")
      )
  )
)

server <- function(input, output) {
  
  output$distPlot <- renderPlot({
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins   1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}
shinyApp(ui = ui, server = server)

(No need to hide the plot for this example.)

I tried selecting input$modify_hist in the sidebarPanel but that didn't work.

Any pointers are appreciated. Thank you!

CodePudding user response:

We can use conditionalPanel which is faster than renderUI as it avoids re-rendering the element:

library(shiny)
ui <- fluidPage(titlePanel("Old Faithful Geyser Data"),
                sidebarLayout(
                  sidebarPanel(
                    width = 3,
                    radioButtons(
                      "modify_hist",
                      "Modify histogram?",
                      choices = c("Yes" = "y", "No" = "n"),
                      selected = "y"
                    ),
                    conditionalPanel(
                      "input.modify_hist == 'y'",
                      sliderInput(
                        "bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30
                      )
                    )
                  ),
                  mainPanel(plotOutput("distPlot"))
                ))

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins   1)
    hist(x,
         breaks = bins,
         col = 'darkgray',
         border = 'white')
  })
}
shinyApp(ui = ui, server = server)

CodePudding user response:

Alternative to the other answer: You can generate the UI in the server, and only generate the bin slider based on the value of input$modify_hist. I also included req(input$bins) in your renderPlot function, to make sure it does not try to plot with having a value for input$bins.

library(shiny)
ui <- fluidPage(
  
  
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      width = 3, 
      radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),
      
      # display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
      uiOutput("slider")
    ),
    
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

server <- function(input, output) {
  
  output$distPlot <- renderPlot({
    req(input$bins)
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins   1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  
  output$slider <- renderUI({
    if(input$modify_hist == "y"){
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
    }
  })
}
shinyApp(ui = ui, server = server)

CodePudding user response:

Also can do it with shinyjs. I am all for using conditionalPanel so all the work is on the client side...

library(shiny)
library(shinyjs)

ui <- fluidPage(
  
  useShinyjs(),
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      width = 3, 
      radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),
      
      # display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
      
      hidden(sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30))),
    
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

server <- function(input, output) {
  
  output$distPlot <- renderPlot({
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins   1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  
  observeEvent(input$modify_hist,{
    if(input$modify_hist=="y"){
      show("bins")
    }else{
      hide("bins")
    }
  })
  
  
  
}
shinyApp(ui = ui, server = server)
  • Related