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)