I'm working on a R/Shiny application and one of its features should be to export data based on some filters. However the filters depends on each other. Consider a list of companies, each companies has some teams or departments and these can be located in different countries. The user can filter the data to export through three drop-down menus (selectInput), but I would like that when one dimension (i.e. group) is selected the choices in the drop-down list for the other two dimensions (i.e. departments and countries) are updated accordingly. However filtering on a second dimension (i.e. departments) should narrow down the selection rather than updating all the selectInput's choices.
The code below is the closest I could get to the desired output. However there are two problems. First, filtering on a second dimension does not narrow down the selection, but updates also the choices for the first selected dimension. Second, even though the choices are updated the selection is not kept in the input field which remains blank.
Any idea how to approach this problem ?
Edit
The code below is almost working. Right now no matters which dimension is selected first, the choices for the remaining two dimensions are correctly updated and filtering on a second dimension does narrow down the selection. However, I'm not able to select more than one item per selectInput despite the multiple = TRUE.
Any idea on how to solve this problem ?
library(shiny)
library(dplyr)
## Create dataframe
group <- rep(toupper(letters[1:3]),each=3)
department <- c("a","b","c","a","b","d","b","c","d")
country <- c("IT","FR","DE","IT","DE","HU","HU","FR","FR")
df <- data.frame(group, department, country)
## Simple user interface with 3 selectInput
ui <- fluidPage(
selectInput('group', 'Group:', df$group, multiple=TRUE, selectize=T),
selectInput('dept', 'Department:', df$department, multiple=TRUE, selectize=T),
selectInput('country', 'Country:', df$country, multiple=TRUE, selectize=T),
tableOutput("table1")
)
filter_names <- c("input$group", "input$dept", "input$country")
filters <- c("group %in% input$group", "department %in% input$dept","country %in% input$country")
checknull <- NULL
server=function(input,output,session) {
## reactive block to update the choices in the select input fields
choices <- reactive({
for (i in seq_along(filter_names)) {
checknull[i] <- eval(parse(text=paste0("!is.null(", filter_names[i], ")",sep="")))
}
req(filters[checknull])
tmp <- eval(parse(text=paste0("filter(df, ", paste0(filters[checknull], collapse = " & "), ")")))
return(tmp)
})
## updateSelectInput
observe({
updateSelectInput(session,'group', choices=sort(unique(choices()$group)), selected = input$group)
updateSelectInput(session,'dept', choices=sort(unique(choices()$department)), selected = input$dept)
updateSelectInput(session,'country', choices=sort(unique(choices()$country)), selected = input$country)
})
output$table1 <- renderTable({df})
}
shinyApp(ui,server)