Home > Back-end >  Update Radio buttons using a Reactive Value fed to a Module, R Shiny
Update Radio buttons using a Reactive Value fed to a Module, R Shiny

Time:11-17

I am building a shiny app and will have the same radio button inputs on multiple pages that will change what is shown on the page. I am putting these radio buttons inside a module so I don't have to reproduce that code in multiple places. They will all have a static set of choices, but I want them all to maintain the same selected value throughout the app. This will mean any time you change a page, the same value is selected as before. If I select A on one page, all other pages will have A selected as well until I choose a different option on any other page.

I haven't been having any luck with any of my attempts thus far. This explanation seems close to what I am looking for, but I haven't been able to make it work. In the app below I feel like I should be able to pass the modServer function a reactive value that will update the associated radio buttons to the same selected value. If I can make this single module update based on input$tmp I think I should be able to replicate that across multiple iterations of the module.

EDIT: Updated code. App now has checks to look at the value of input$tmp outside of the module as itself and a reactive value. Also within the module as the input as well as a new reactive value.

New Question: Why is it showing none of these variables as a reactive variable? It must be why the observeEvent isn't working inside the modServer. The renderText show those values are updating, but it's not triggering the updateRadioGroupButtons.

library(shiny)
library(shinyWidgets)

# UI module
modUI <- function(id){
  ns <- NS(id)
  tagList(
      shinyWidgets::radioGroupButtons(
        inputId = ns("radio"),
        choices = c('A', 'B', 'C', 'D'),
        selected = 'A'),
      uiOutput(ns('modtest')),
      uiOutput(ns('modtest2'))
  )

}
# Server module
modServer <- function(id, .selected){
  moduleServer( id, function(input, output, session){
    ns <- session$ns
  
    mod_rval <- reactive({ .selected() })    
        
    output$modtest <- renderText({
      paste('mod_rval() is:', mod_rval(), 'and is reactive: ', is.reactive(mod_rval()))
    })
    
    output$modtest2 <- renderText({
      paste('.selected() is:', .selected(), 'and is reactive: ', is.reactive(.selected()))
    })
    
    observeEvent(.selected(), {
      shinyWidgets::updateRadioGroupButtons(
        session,
        inputId = ns("radio"),
        choices = c('A', 'B', 'C', 'D'),
        selected = .selected()
      )
    })
  
  })
}

# APP
ui <- fluidPage(
  selectInput('tmp', 'tmp : input value', choices = c('A','B','C','D')),
  modUI(id='mod1'),
  uiOutput('test'),
  uiOutput('test2')
)

server <- function(input, output, session) {
  
  # functioning.
  rval <- reactive({input$tmp})
  modServer(id = 'mod1', .selected = rval)

  output$test <- renderText({
    paste('rval() is: ', rval(), 'and is reactive: ', is.reactive(rval()))
  })
  
  output$test2 <- renderText({
    paste('input$tmp is: ', input$tmp, 'and is reactive: ', is.reactive(input$tmp))
  })
  
}

shinyApp(ui, server)

CodePudding user response:

You don't need ns in updateRadioGroupButtons(...), and you really need to update in a different server module as one is affecting the other. Try this

library(shiny)
library(shinyWidgets)

# UI module
modUI <- function(id){
  ns <- NS(id)
  shinyWidgets::radioGroupButtons(
    inputId = ns("radio"),
    choices = c('A', 'B', 'OK', 'Whatever'),
    selected = 'A')
  
}
# Server module 1
modServe <- function(id){
  moduleServer( id, function(input, output, session){
    return(reactive(input$radio))
  })
}
# Server module 2
modServer <- function(id, selected){
  moduleServer( id, function(input, output, session){
    
    observe({
      print(selected())
      shinyWidgets::updateRadioGroupButtons(
        session,
        inputId = "radio",
        choices = c('A', 'B', 'C', 'D'),
        selected = selected()
      )
    })
    
  })
}

# APP
ui <- fluidPage(
  modUI(id='mod1'),
  modUI(id='mod2')
)

server <- function(input, output, session) {
  m1 <- modServe("mod1")
  m2 <- modServe("mod2")
  
  modServer("mod2",m1)
  modServer("mod1",m2)
}

shinyApp(ui, server)
  • Related