0

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)
MLEN
  • 2,162
  • 2
  • 20
  • 36

1 Answers1

1

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)
Bertil Baron
  • 4,923
  • 1
  • 15
  • 24
  • 1
    I want to note the "selected = input$candy" is what keeps the UI from not defaulting to the first value for single-select lists and no values for multiple select lists. – Shafquat Feb 28 '20 at 13:49