I have a module in which I create a list of inputs based on a reactive value: if this value is 3, then 3 textInput
s are created, etc. Until now, when I needed to return inputs/values from a module, I listed all of the inputs/values in return()
at the end of the server
part of my module (see this article for more details).
But in this situation, since the number of inputs is not constant, I can't list all of the inputs in return()
. Therefore, I would like to create a reactive list that I could return.
Consider the example below:
library(shiny)
some_things <- c("drat", "mpg", "cyl")
numtextinputs <- length(some_things)
some_UI <- function(id) {
ns <- NS(id)
tagList(
fluidRow(
column(
12,
lapply(1:numtextinputs, function(x) {
textInput(ns(some_things[x]),
label = some_things[x],
value = some_things[x])
}),
actionButton(ns("change"), "change inputs")
)
)
)
}
some_server <- function(input, output, session) {
observeEvent(input$change, {
test <- list()
char_numtextinputs <- as.character(numtextinputs)
for (x in char_numtextinputs) {
local({
test[[x]] <- input[[some_things[x]]]
})
}
return(reactive({ test }) )
})
}
ui <- fluidPage(
actionButton("create_ui", "create ui"),
uiOutput("ui"),
verbatimTextOutput("display_changes")
)
server <- function(input, output, session) {
observeEvent(input$create_ui, {
output$ui <- renderUI({
some_UI("1")
})
list_of_variables <- callModule(some_server, "1")
})
output$display_changes <- renderText({
if (exists("list_of_variables")){
list_of_variables$test()
}
else {
"list_of_variables$test does not exist"
}
})
}
shinyApp(ui, server)
In this example, clicking on "create ui" generates a list of textInput
s. Note that here, the number of textInput
s created is constant (I wanted to have a simple example, adding some reactivity in the number of inputs to be created is not very useful).
Expected result: after having generated the list of textInput
s, the user can modify the values in those and click on "change inputs" when he/she has finished. The module should then return the values in the textInput
s as a vector. The verbatimTextOutput
is just here to verify that the values are well returned. Note that the answer should work with any number of textInput
s (this is why I tried lists and loop).
Also asked on StackOverflow