I got this answer previously: observeEvent in Shiny using functions but I am having trouble implementing this using modules.
I am looking to update the inputs, via a function. Updating one radio button should update the others. I have tried to update the previous answer, but I can't quite get it to work.
So this works, but doesn't use a function:
library(shinydashboard)
library(shiny)
library(glue)
library(rlang)
library(tidyverse)
# module --------------
# Choice of variables
choice_ui <- function(id) {
ns <- NS(id)
tagList(
radioButtons(ns("species"),
label = "species",
choices = unique(iris$Species),
selected = "setosa")
)
}
choice_server <- function(id, rv) {
moduleServer(id, function(input, output, session) {
# Whenever the choice changes, the value inside rv is set
observeEvent(input$species, {
rv$species <- input$species
})
})
}
# app -------------
ui <- dashboardPage(
dashboardHeader(title = "test"),
dashboardSidebar(
sidebarMenu(id = "tabs",
# Introduction -----------------------------------------------------------
menuItem("tab1", tabName = "tab1"),
conditionalPanel("input.tabs == 'tab1'",
choice_ui("sp1")
),
# Current applications -----------------------------------------------------------
menuItem("tab2", tabName = "tab2"),
conditionalPanel("input.tabs == 'tab2'",
choice_ui("sp2")
),
# Completed applications -----------------------------------------------------------
menuItem("tab3", tabName = "tab3"),
conditionalPanel("input.tabs == 'tab3'",
choice_ui("sp3")
)
)
),
dashboardBody(
"Not relevant."
)
)
server <- function(input, output, session) {
# reactive values ----------
rv <- reactiveValues()
# observe normally ----------
# this works
observeEvent(input[['sp1-species']],{
updateRadioButtons(session,
'sp2-species',
selected = input[['sp1-species']])
updateRadioButtons(session,
'sp3-species',
selected = input[['sp1-species']])
})
observeEvent(input[['sp2-species']],{
updateRadioButtons(session,
'sp1-species',
selected = input[['sp2-species']])
updateRadioButtons(session,
'sp3-species',
selected = input[['sp2-species']])
})
observeEvent(input[['sp3-species']],{
updateRadioButtons(session,
'sp2-species',
selected = input[['sp3-species']])
updateRadioButtons(session,
'sp3-species',
selected = input[['sp3-species']])
})
# module servers
choice_server("sp1", rv = rv)
choice_server("sp2", rv = rv)
choice_server("sp3", rv = rv)
}
shinyApp(ui, server)
This is the code using a function, but it doesn't update the inputs properly. There are some outputs printed in the console for testing purposes if that is helpful.
library(shinydashboard)
library(shiny)
library(glue)
library(rlang)
library(tidyverse)
# module --------------
# Choice of variables
choice_ui <- function(id) {
ns <- NS(id)
tagList(
radioButtons(ns("species"),
label = "species",
choices = unique(iris$Species),
selected = "setosa")
)
}
choice_server <- function(id, rv) {
moduleServer(id, function(input, output, session) {
# Whenever the choice changes, the value inside rv is set
observeEvent(input$species, {
rv$species <- input$species
})
})
}
# function ----------------
species_observer <- function(source){
others <- setdiff(c('sp1-species','sp2-species','sp3-species'), source)
glue("
observeEvent(input[['{source}']],
{{
# just looking at the outputs ---
print('{source}')
print(input[['{source}']])
print(paste('first: ', input[['{others[1]}']])) # not quite right
print(paste('second: ', input[['{others[2]}']])) # not quite right
# update ----
updateRadioButtons(session,
input[['{others[1]}']],
selected = input[['{source}']])
updateRadioButtons(session,
input[['{others[2]}']],
selected = input[['{source}']])
}})")
}
# app -------------
ui <- dashboardPage(
dashboardHeader(title = "test"),
dashboardSidebar(
sidebarMenu(id = "tabs",
# Introduction -----------------------------------------------------------
menuItem("tab1", tabName = "tab1"),
conditionalPanel("input.tabs == 'tab1'",
choice_ui("sp1")
),
# Current applications -----------------------------------------------------------
menuItem("tab2", tabName = "tab2"),
conditionalPanel("input.tabs == 'tab2'",
choice_ui("sp2")
),
# Completed applications -----------------------------------------------------------
menuItem("tab3", tabName = "tab3"),
conditionalPanel("input.tabs == 'tab3'",
choice_ui("sp3")
)
)
),
dashboardBody(
"Note the outputs being printed in the console."
)
)
server <- function(input, output, session) {
# reactive values ----------
rv <- reactiveValues()
# observe using function ----------
walk(paste0("sp", 1:3, "-species"),
~eval(parse_expr(species_observer(.x))))
# module servers
choice_server("sp1", rv = rv)
choice_server("sp2", rv = rv)
choice_server("sp3", rv = rv)
}
shinyApp(ui, server)