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)