rshinyuioutput

How to correctly use a checkboxInput 'All/None' in a uiOutput context in R Shiny?


Here is the context :

library(shiny)

liste_statut <- c("A","B","C")

ui <- shinyUI(fluidPage(uiOutput("testUI")))
server <- function(input, output, session) {

   output$testUI <- renderUI({

    navbarPage(
      title = "Test",

  tabPanel(icon = icon("users"), 'Test',

           sidebarPanel(
             # Statut
             checkboxGroupInput("statut", "Statut", liste_statut, liste_statut),
             checkboxInput('selectall_statut', 'Tout / Aucun', T))))

})

  # observe({
  #   updateCheckboxGroupInput(
  #     session, 'statut', choices = liste_statut,
  #     selected = if (input$selectall_statut) liste_statut
  #   )
  # })
}

 shinyApp(ui = ui, server = server)

I would like to use my checkbox All/None (in comment lines) properly cause in this case i have a "Warning: Error in if: argument is of length zero". Where should i put it or maybe should i redefine properly something in the UI part?

I willingly use the renderUI/uiOutput option (contrary to the "standard mode" ui/server) because in future, i will add an authentification module, so be able to display several "panels" according to user.

Thanks and sorry for my terrible english :).


Solution

  • The following works for me:

    library(shiny)
    liste_statut <- c("A","B","C")
    
    ui <- shinyUI(fluidPage(uiOutput("testUI")))
    server <- function(input, output, session) {
    
      output$testUI <- renderUI({
    
        navbarPage(
          title = "Test",
    
          tabPanel(icon = icon("users"), 'Test',
    
                   sidebarPanel(
                     # Statut
                     checkboxGroupInput("statut", "Statut", liste_statut, liste_statut),
                     checkboxInput('selectall_statut', 'Tout / Aucun', T))))
    
      })
    
      observeEvent(input$selectall_statut,{
        val <- liste_statut
        if(!input$selectall_statut)
          val <- character(0)
    
        updateCheckboxGroupInput(
          session, 'statut', 
          selected = val
        )
      })
    }
    

    I initially tried selected = ifelse(input$selectall_statut, liste_statut, character(0)) instead of the intermediate variable val. However, ifelse() only returned a single value, not a vector.

    If you are going to do this many times over, then I would recommend a custom ifelse function. Perhaps something like the following:

    ifelse2 <- function(test, yes, no){
        if(test)
            return(yes)
        return(no)
    }