Want to update element when user clears selection in selectizeInput

In a Shiny app, I have two lists. And I want the options in list 1 to be downselected if user selects something in list 2.

  • Initially
    • List 1 has following choices: 'ab', 'bb', 'cc', 'dc', 'bc'
    • List 2 has following choices: 'b', 'c'
    • Nothing is selected by default
  • If user selects only b in list 2
    • List 1 downselects to 'ab', 'bb', 'bc' i.e. elements that contain b
  • If user selects only c in list 2
    • List 1 downselects to 'cc', 'dc', 'bc' i.e. elements that contain c
  • If user selects both b and c in list 2
    • List 1 downselects to bc i.e. elements that contain b and c

I have an implementation below that works OK for the above logic.

My problem is that after user does any kind of selection in list 2, and then empties list 2, list 1 does not update to the original list of five elements. Can someone suggest a solution?

library(shiny)

ui <- fluidPage(
   
   # Application title
   titlePanel("List 1 depends on partial match with all items from List 2"),
   
   sidebarLayout(
      sidebarPanel(
         selectizeInput('list1', 					
                        label = 'List 1',
                        choices = c('ab', 'bb', 'cc', 'dc', 'bc'),
                        multiple = TRUE,
                        selected = NULL
         ),
         selectizeInput('list2', 					
                        label = 'List 2',
                        choices = c('b', 'c'),
                        multiple = TRUE,
                        selected = NULL
         )
      ),
      
      mainPanel(
      )
   )
)

server <- function(input, output, session) {
   observeEvent(input$list2, {
     choices = c('ab', 'bb', 'cc', 'dc', 'bc')
     if (!is.null(input$list2)) {
       if (length(input$list2) == 1) {
         choices = grep(input$list2, choices, value = TRUE)
       } else if (length(input$list2) == 2) {
         L1 = lapply(input$list2, function(elem) grepl(elem, choices))
         matched = sapply(1:length(L1[[1]]), function(idx) L1[[1]][idx] & L1[[2]][idx])
         choices = choices[matched]
       }
     }
     updateSelectizeInput(session, 'list1', choices = choices)
   })
   
}

# Run the application 
shinyApp(ui = ui, server = server)

The problem is that the observeEvent() function isn't getting triggered when list2 is empty. To change this, you simply add the argument ignoreNULL = FALSE:

server <- function(input, output, session) {
  observeEvent(input$list2, ignoreNULL=FALSE, {
    choices = c('ab', 'bb', 'cc', 'dc', 'bc')
    if (!is.null(input$list2)) {
      if (length(input$list2) == 1) {
        choices = grep(input$list2, choices, value = TRUE)
      } else if (length(input$list2) == 2) {
        L1 = lapply(input$list2, function(elem) grepl(elem, choices))
        matched = sapply(1:length(L1[[1]]), function(idx) L1[[1]][idx] & L1[[2]][idx])
        choices = choices[matched]
      }
    }
    updateSelectizeInput(session, 'list1', choices = choices)
  })
  
}
2 Likes

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.