Shiny: update(multi)Input based on reactive values

Hey.
I am struggling to implement updateMultiInput with reactive values. See the example with murders dataset bellow. Basically I am trying to apply a global selectInput filter which filters the data based on region. After that I want to use the multiInput to show me unique states of the filtered dataset & use the multiInput for secondary filtering based on the states.
Also if there is a solution using crosstalk with these two specific inputs, I am all ears!

Thank you!

install.packages("dslabs")
library(dslabs)
library(shiny)
library(dplyr)
library(shinyWidgets)
data("murders")

ui = fluidPage(
  selectInput("region", "Select region:", choices = unique(murders$region)),
  multiInput(
    "state",
    "Selected state:",
    choices = "",
    width = "600px"
  )
  dataTableOutput("tbl")
)

server = function(input, output, session){
  df = 
    reactive({
      murders %>% 
        filter(region == input$region)
      })
  
  output$tbl = renderDataTable(df()) # check if global filter works OK

  #This does not work
  # updateMultiInput(
  #   "state",
  #   selected = "",
  #   choices = reactive(unique(df()$state)))
}

shinyApp(ui, server)

This should be solved using renderUI server-side, instead updateInput. See the solution bellow. I am leaving it here in case someone is solving a same problem or has come up with some interesting solution other than renderUI.

install.packages("dslabs")
library(dslabs)
data("murders")

ui = fluidPage(
  selectInput("region", "Select region:", choices = unique(murders$region)),
  uiOutput("state"),
  dataTableOutput("tbl")
)

server = function(input, output, session){
  df = 
    reactive({
      murders %>% 
        filter(region == input$region)
    })
  
  output$tbl = renderDataTable(df()) # check if global filter works OK
  output$state = renderUI(
    multiInput(
      inputId = "state",
      label = "Select state",
      selected = "",
      choices = unique(df()$state)
      )
  )
  }
 

shinyApp(ui, server)

For record, also the version with updateMultiInput is possible when wrapped in observe().
It is also most desirable in my case because multiInput will be hidden in the dropdownButton widget. The update version renders the table on the start of the app (see code example 1) instead of after clicking the dropdownButton (code example 2) with renderUI.


#VERSION1
#option with updateinput with widgets


data("murders")

ui = fluidPage(
  selectInput("region", "Select region:", choices = unique(murders$region)),
  dropdownButton(
    inputId = "Button",
    circle = TRUE, 
    status = "danger", 
    icon = icon("gear"),
    multiInput(
      "state",
      "Selected state:",
      choices = "",
      width = "600px"
    )
  ),
  dataTableOutput("tbl")
)

server = function(input, output, session){
  df = 
    reactive({
      murders %>% 
        filter(region == input$region)
    })
  
  output$tbl = renderDataTable(df()) # check if global filter works OK
  states = reactive({as.character(unique(df()$state))})
  
  observe({
    updateMultiInput(
      session,
      "state",
      selected = "",
      choices = states())
  }
  )
}

shinyApp(ui, server)


#VERSION2
# option with renderUI  
library(dslabs)
data("murders")

ui = fluidPage(
  selectInput("region", "Select region:", choices = unique(murders$region)),
  dropdownButton(
    inputId = "Button",
    circle = TRUE, 
    status = "danger", 
    icon = icon("gear"),
    uiOutput("state")
  ),
  dataTableOutput("tbl")
)

server = function(input, output, session){
  df = 
    reactive({
      murders %>% 
        filter(region == input$region)
    })
  df1 = reactive({
    df() %>% 
      filter(state %in% input$state)
  })
  
  output$state = renderUI(
    multiInput(
      inputId = "state",
      label = "Select state",
      selected = unique(df()$state),
      choices = unique(df()$state)
    )
  )

  output$tbl = renderDataTable(df1()) # check if global filter works OK
  }
 

shinyApp(ui, server)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.