updateSelectInput in modularised user interface

Hi there,
I am trying to update a select input based on another select input. I'm not sure why it isn't working, but it is getting complex as I am trying to use modules to avoid replication. I have created a minimal (arguably) example:

library(shiny)

commonUI <- function(id) {
  ns <- NS(id)
  tagList(
    selectInput(ns('year'), 'Survey year', choices = c('All'='*','2018','2016','2014','2012','2010'), selected = '2018'),
    selectInput(ns('by'), 'Plot by', choices = c('All','Sex','Year group', 'Survey year'))
  )
}

prepdata <- function(input, output, session, by = NULL){
  yearupdate <- reactive({
    ns <- session$ns
    if(by == 'Survey year'){
      updateSelectInput(session, ns('year'), selected = '*')
    }
  })
}

ui <- fluidPage(
  tabsetPanel(
    tabPanel('Summary',
      commonUI('tab1')
    ),
    tabPanel('Custom',
      commonUI('tab2')
    )
  )
)

server <- function(input, output, session){
	summdat <- callModule(prepdata, 'tab1', by = reactive(input$by))
	custdat <- callModule(prepdata, 'tab2', by = reactive(input$by))
}

shinyApp(ui, server)

If anyone knows why it isn't working, I would love to know! :slight_smile:
I'm still new at using modules!

Will

Hi @WillP. Your code have a number of errors. First, no need to add namespace to the inputId inside module, so no need ns <- session$ns. Use observe instead of reactive inside prepdata function. No need to pass reactive(input$by), just use input$by directly inside module. And your module didn't return anything, so no need to assign to summdat and custdat. Try the follow code. Hope it can help.

library(shiny)

commonUI <- function(id) {
  ns <- NS(id)
  tagList(
    selectInput(ns('year'), 'Survey year', choices = c('All'='*','2018','2016','2014','2012','2010'), selected = '2018'),
    selectInput(ns('by'), 'Plot by', choices = c('All','Sex','Year group', 'Survey year'))
  )
}

prepdata <- function(input, output, session){
  observe(
    { 
      req(input$by)
      if(input$by == 'Survey year'){
        updateSelectInput(session, 'year', selected = '*')
      }
    }
  )
}

ui <- fluidPage(
  tabsetPanel(
    tabPanel('Summary',
             commonUI('tab1')
    ),
    tabPanel('Custom',
             commonUI('tab2')
    )
  )
)

server <- function(input, output, session){
  callModule(prepdata, 'tab1')
  callModule(prepdata, 'tab2')
}

shinyApp(ui, server)
2 Likes

Great, thanks for that Raytong, works like a dream!

Will

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