set state of modular inputs with `actionButton`

Greetings Rstudio Community! Thanks in advance.

My initial goal was to create a button that will set the state of my inputs in a shiny app. In particular, I'm setting the state of module inputs--though I'm not sure this detail matters.

In this reprex, the app has two text input fields (which initially default to hello and goodbye). If you press the Apply Preset button, it should update the fields to peace and love. This works the first time you press it--using a reactiveValues field to keep track of what the presets should be. However, it does not work more than once, because the reactiveValues don't update when the text is updated by the user. Thus, pressing the "reset" value a second time doesn't actually change anything inside the app, and doesn't trigger updating the default value in test_ui.

This is the closest I've gotten to my solution though--I'm open to pursuing a totally different strategy (not using the reactiveValues, for example). Eventually I will need to be able to set multiple different preset buttons. Thanks thanks thanks!

library(shiny)

test_ui <- function(id, default_val) {
  ns <- NS(id)
  textInput(ns("text"), "Put Text Here", value = default_val)
}

test <- function(input, output, session) {
  return(list(text = reactive({input$text})))
}

ui <- fluidPage(
  actionButton("preset", "Apply Presets"),
  uiOutput("testtest"),
  verbatimTextOutput("text")
)

server <- function(input, output, session) {
  presets1 <- reactiveValues(
    default_val = "hello"
  )
  
  presets2 <- reactiveValues(
    default_val = "goodbye"
  )
  
  observeEvent(input$preset, {
    presets1$default_val <- "peace"
    presets2$default_val <- "love"
  })
  
  output$testtest <- renderUI({
    tagList(
      test_ui("text1", presets1$default_val),
      test_ui("text2", presets2$default_val)
    )
  })
  
  choices <- list(
    text1 = callModule(test, "text1"),
    text2 = callModule(test, "text2")
  )
  
  output$text <- renderPrint({
    paste(choices$text1$text(), choices$text2$text())
  })
}

shinyApp(ui, server)

I'm not sure if this is the issue because the overall architecture is a bit confusing to me. But I think the issue is that you need to refer to presets somewhere in the final rendering. I.e. renderPrint() needs to include the presets reactive values so it knows to update when presets updates.

Is there a reason you're using reactiveValues instead of updateTextInput? https://shiny.rstudio.com/reference/shiny/0.14/updateTextInput.html

I hadn't used updateTextInput because I thought it wouldn't work with my modules, but this SO post helped me out. And you were right--reactiveValues does overcomplicate the situation. I think this solution does what i was looking for:

library(shiny)

# module ----------------------------------------------
test_ui <- function(id, default_val) {
  ns <- NS(id)
  textInput(ns("text"), "Put Text Here", value = default_val)
}

test <- function(input, output, session, preset, preset_val) {
  observeEvent(
    preset(),
    updateTextInput(session, "text", value = preset_val)
  )
  
  return(list(text = reactive({input$text})))
}

# ui --------------------------------------------------
ui <- fluidPage(
  actionButton("preset", "Apply Presets"),
  test_ui("text1", "hello"),
  test_ui("text2", "goodbye"),
  verbatimTextOutput("text")
)

# server ----------------------------------------------
server <- function(input, output, session) {
  
  choices <- list(
    text1 = callModule(test, "text1", reactive(input$preset), "peace"),
    text2 = callModule(test, "text2", reactive(input$preset), "love")
  )
  
  output$text <- renderPrint({
    paste(choices$text1$text(), choices$text2$text())
  })
}

shinyApp(ui, server)