简体   繁体   中英

Shiny App checkboxInput and conditionalPanel

I am new to ShinyApp.

I want to use a checkboxInput() with conditionalPanel, so when it's checked, the options for Type will show up (then users can select a Type from "BEER", "REFRESHMENT", "SPIRITS", "WINE"). If it's not checked, the options for Type will not show up.

Below are my code, but when the Type options didn't show no matter I check the box or not. I guess I should write something in the server function? I really don't know. Thank you for your help.

  ui <- fluidPage(
        titlePanel("BC Liquor Store prices"),
        img(src = "BCLS.png",align = "right"),
        sidebarLayout(
             sidebarPanel(sliderInput("priceInput", "Price", 0, 100, c(25, 40), pre = "$"),

            wellPanel(
            checkboxInput("checkbox", "Filter by Type", FALSE),
            conditionalPanel(
              condition="checkbox==true",   
             selectInput("typeInput", "Product type",
                          choices = c("BEER", "REFRESHMENT", "SPIRITS", "WINE"),
                          selected = "WINE")
          )
        ),

             uiOutput("countryOutput")

),
mainPanel(
  tabsetPanel(
    tabPanel("Plot", plotOutput("coolplot")), 
    tabPanel("Summary", verbatimTextOutput("summary")), 
    tabPanel("Table", tableOutput("results"))
   )
  )
 )
)

server <- function(input, output, session) {
      output$countryOutput <- renderUI({
      selectInput("countryInput", "Country",
            sort(unique(bcl$Country)),
            selected = "CANADA")
  })  

     filtered <- reactive({
        if (is.null(input$countryInput)) {
        return(NULL)
}    

bcl %>%
  filter(Price >= input$priceInput[1],
         Price <= input$priceInput[2],
         Type == input$typeInput,
         Country == input$countryInput
  )
})

     output$coolplot <- renderPlot({
         if (is.null(filtered())) {
         return()
      }
     filtered() %>% ggvis(~Alcohol_Content, fill := "#fff8dc") %>% 
        layer_histograms(width = 1, center = 0)
   })

 output$results <- renderTable({
filtered()
 })
}

I came across this question recently while researching a similar one .

It seems the simple answer to the checkboxInput condition is as below:

condition="input.checkbox==1",

OK, you can classify conditional inputs in two categories.

1) Inputs that depend on the ui.R (in your case the checkboxInput)

2) Inputs that depend on the server.R (not necessary in your example)

Solutions:

1) you can easily solve with a renderUI() function, see the example below.

If you really want 2), you would need a conditionalPanel and you would use a reactive function in the server.R, that you save in an output object and access it with small JS-snippet in the ui.R. For me it looks like 1) is enough for you, if I am mistaken, let me know then we adapt the answer to solve 2).

A hint:

As a default your "checkbox" input takes the boolean value: false. So you would not render the "typeInput" (until you click "checkbox"). So up to that point "typeInput" is null. However, if you now make dependencies on "typeInput" shiny will be confused, since "typeInput" is not rendered and therefore does not exist. So before using "typeInput", you should check, whether it is available: if(!is.null(input$typeInput)) otherwise shiny will complain that you actually do not have a "typeinput" in your app (again: at least until you click "checkbox").

ui <- fluidPage(
  titlePanel("BC Liquor Store prices"),
  img(src = "BCLS.png",align = "right"),
  sidebarLayout(
    sidebarPanel(sliderInput("priceInput", "Price", 0, 100, c(25, 40), pre = "$"),

                 wellPanel(
                   checkboxInput("checkbox", "Filter by Type", FALSE),
                   uiOutput("conditionalInput")
                 ),

                 uiOutput("countryOutput")

    ),
    mainPanel(
      tabsetPanel(
        tabPanel("Plot", plotOutput("coolplot")), 
        tabPanel("Summary", verbatimTextOutput("summary")), 
        tabPanel("Table", tableOutput("results"))
      )
    )
  )
)

server <- function(input, output, session) {
  output$countryOutput <- renderUI({
    selectInput("countryInput", "Country",
                sort(unique(bcl$Country)),
                selected = "CANADA")
  })  

  output$conditionalInput <- renderUI({
    if(input$checkbox){
      selectInput("typeInput", "Product type",
                  choices = c("BEER", "REFRESHMENT", "SPIRITS", "WINE"),
                  selected = "WINE")
    }
  })

  filtered <- reactive({
    if (is.null(input$countryInput)) {
      return(NULL)
    }    

    bcl %>%
      filter(Price >= input$priceInput[1],
             Price <= input$priceInput[2],
             Type == input$typeInput,
             Country == input$countryInput
      )
  })

  output$coolplot <- renderPlot({
    if (is.null(filtered())) {
      return()
    }
    filtered() %>% ggvis(~Alcohol_Content, fill := "#fff8dc") %>% 
      layer_histograms(width = 1, center = 0)
  })

  output$results <- renderTable({
    filtered()
  })
}

# run the app
shinyApp(ui = ui, server = server)

I will add to this answer in case someone, like me, run into this issue while working in a module in Shiny. In this case, using a checkbox as a condition for a conditionalPanel may run into the problem described here: Shiny App checkboxInput and conditionalPanel

tl;dr: in a conditionalPanel in a module in Shiny, the namespace for the checkboxInput influences the condition for the panel. The only solution that worked for me was:

checkboxInput(ns("smooth"), "Smooth"),
conditionalPanel(
 condition = paste0("input['", ns("smooth"), "'] == true"),
 ...
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM