MLEN
MLEN

Reputation: 2561

Dependent filter in shiny inputs

Example taken from: Filter one selectInput based on selection from another selectInput?

I am trying to create a shiny app where the user can select several boxes and then some data is generated. I dont understand if I for example click first "Mars", then the second option Candy is filtered, I would now like to select "Snickers", why does everything restore when clicking snickers?

library(shiny)
library(shinydashboard)
library(shinyWidgets)
##
ui <- shinyUI({
  sidebarPanel(

    htmlOutput("brand_selector"),
    htmlOutput("candy_selector"))

})
##
server <- shinyServer(function(input, output) {
  candyData <- read.table(
    text = "Brand       Candy
    Nestle      100Grand
    Netle       Butterfinger
    Nestle      Crunch
    Hershey's   KitKat
    Hershey's   Reeses
    Hershey's   Mounds
    Mars        Snickers
    Mars        Twix
    Mars        M&Ms",
    header = TRUE,
    stringsAsFactors = FALSE)

  output$brand_selector <- renderUI({

    available2 <- candyData
    if(NROW(input$candy) > 0 ) available2 <- candyData[candyData$Candy %in% input$candy, ]

    pickerInput(
      inputId = "brand", 
      label = "Brand:",
      choices = as.character(unique(available2$Brand)),
      multiple = T,options = list(`actions-box` = TRUE))

  })

  output$candy_selector <- renderUI({

    available <- candyData
    if(NROW(input$brand > 0)) available <- candyData[candyData$Brand %in% input$brand, ]

    pickerInput(
      inputId = "candy", 
      label = "Candy:",
      choices = unique(available$Candy),
      multiple = T,options = list(`actions-box` = TRUE))

  })

})
##
shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 1818

Answers (1)

Bertil Baron
Bertil Baron

Reputation: 5003

the problem comes from that you have your render UI codependent of the input variables and when one changes the whole UI rerendered including the values of the input variables. Fot this use-case you are better of with the update*Input functions. Here is a working version for your example

library(shiny)
library(shinydashboard)
library(shinyWidgets)
##
ui <- shinyUI({
  sidebarPanel(

    htmlOutput("brand_selector"),
    htmlOutput("candy_selector"))

})
##
server <- shinyServer(function(input, output,session) {
  candyData <- read.table(
    text = "Brand       Candy
    Nestle      100Grand
    Netle       Butterfinger
    Nestle      Crunch
    Hershey's   KitKat
    Hershey's   Reeses
    Hershey's   Mounds
    Mars        Snickers
    Mars        Twix
    Mars        M&Ms",
    header = TRUE,
    stringsAsFactors = FALSE)
  observeEvent({
    input$candy
  },
  {
    available2 <- candyData
    if(NROW(input$candy) > 0 ) available2 <- candyData[candyData$Candy %in% input$candy, ]
    updatePickerInput(
      session = session,
      inputId = "brand", 
      choices = as.character(unique(available2$Brand)),
      selected = input$brand
    )
  },
  ignoreInit = FALSE,
  ignoreNULL = FALSE)
  output$brand_selector <- renderUI({


    pickerInput(
      inputId = "brand", 
      label = "Brand:",
      choices = NULL,
      multiple = T,options = list(`actions-box` = TRUE))

  })
  observeEvent({
   input$brand
  },{
    available <- candyData
    if(NROW(input$brand > 0)) available <- candyData[candyData$Brand %in% input$brand, ]
    updatePickerInput(
      session = session,
      inputId = "candy",
      choices = unique(available$Candy),
      selected = input$candy
    )
  },
  ignoreInit = FALSE,
  ignoreNULL = FALSE)
  output$candy_selector <- renderUI({


    pickerInput(
      inputId = "candy", 
      label = "Candy:",
      choices = NULL,
      multiple = T,options = list(`actions-box` = TRUE))

  })

})
##
shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions