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
- List 1 has following choices:
- If user selects only
b
in list 2- List 1 downselects to
'ab', 'bb', 'bc'
i.e. elements that containb
- List 1 downselects to
- If user selects only
c
in list 2- List 1 downselects to
'cc', 'dc', 'bc'
i.e. elements that containc
- List 1 downselects to
- If user selects both
b
andc
in list 2- List 1 downselects to
bc
i.e. elements that containb
andc
- List 1 downselects to
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)