Dynamic and flexible checkboxGroupInput in shiny

My goal is to create a reactive checkboxGroupInput which changes based on user selection. I have done this using observe() and updateCheckboxGroupInput. The problem is that the options I would like to provide the user vary in length and value. Is there another way to achieve this which is more flexible? It seems like one solution would be to use several conditionalPanels but I feel like there has to be a better way to do this. Thanks in advance!

Here is a reproducible example. Desired checkbox options to display for each condition:

Condition1 - a, b, c

Condition2 - a, b, c, d

Condition3 - a

Below is what ends up being displayed. I have to add a value to the list of Condition1 to avoid an error, and Condition3 is duplicated to match the length of Condition2.

Condition1 - a, b ,c, extra_val_so_no_error

Condition2 - a, b, c, d

Condition3 - a, a, a, a

library(shiny)

ui <- fluidPage(

    titlePanel("reproducible example checkboxGroupInput question"),

    mainPanel(
        selectInput("condition",
                    label = h5("Select a condition:"),
                    choices = list("Condition 1" = 1,
                                   "Condition 2" = 2,
                                   "Condition 3" = 3),
                    selected = "1"
        ),
        checkboxGroupInput("dynamic",
                           label = h5("Select one or more:"),
                           choices = NULL,
                           selected = NULL
        ),
    )
)

server <- function(input, output, session) {

    observe(updateCheckboxGroupInput(session = session,
                                     inputId = "dynamic",
                                     choices = case_when(input$condition == "1" ~ list("a", "b", "c", "extra_val_so_no_error"),
                                                         input$condition == "2" ~ list("a", "b", "c", "d"),
                                                         input$condition == "3" ~ list("a")),
                                     selected = "a")
    )
}

shinyApp(ui = ui, server = server)

I've done something similar, so I used my old code as a template. Note: it was a while ago, so there may be better ways of coding this, BUT it works.

library(shiny)

ui <- fluidPage(
  
  titlePanel("reproducible example checkboxGroupInput question"),
  
  mainPanel(
    selectInput("condition",
                label = h5("Select a condition:"),
                choices = c( "Condition 1",
                             "Condition 2",
                             "Condition 3"),
                selected = "Condition 1"
    ),
    checkboxGroupInput("dynamic",
                       label = h5("Select one or more:"),
                       choices = ''),
  )
)



server <- function(input, output, session) {
  
  observe({
    if(input$condition == "Condition 1")
      choices <- c("a", "b", "c")
    else if(input$condition == "Condition 2")
      choices <- c("a", "b", "c", "d")    
    else if(input$condition == "Condition 3")
      choices <- "a"
    
    selected <- choices[1]
    
    updateCheckboxGroupInput(session = session,
                             inputId = "dynamic",
                             choices = choices,
                             selected = selected)
  })
}

shinyApp(ui = ui, server = server)
1 Like

Thank you very much veronix! Clearly I need to debug my code better, because the error was coming from case_when() and not updateCheckboxGroupInput. I incorrectly assumed that updateCheckboxGroupInput was forcing me to have equal length vectors as choices. There may have been a stack overflow post out there though which corroborated this assumption too :thinking:

1 Like

No problem, glad you were able to pin it down. And hey, it happens to everyone - sometimes you take a step back from debugging, then come back later and what didn't make sense at all becomes glaringly obvious :wink:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.