I want to create a dynamic UI in Shiny, where each time a button is clicked, a new UI element is created with several input fields. I was hoping that I could do this using reactiveValues, however the ui code can't access them, so I can't tell it how many elements to show.
Here's a reproducible example with just a single UI field created on each click - it works for the first two clicks of the button, but since the lapply in the ui section is coded to a fixed value (3 in this example), after that the new ones stop being displayed. I know I could set the ui value at a higher number, but what I'd like is for it to be reactive. (In the full version I'd like to have nested elements within each of these that work the same way, and buttons to remove each field as well.)
server <- function(input, output) {
rv <- reactiveValues(numFields = 1)
#
# start with one input box
#
output$textUI1 <- renderUI(textInput("textInput1", "Input #1"))
#
# each time the button is clicked, increase the reactive value
#
observeEvent(input$addField, rv$numFields <- rv$numFields + 1)
#
# render any additional UI input fields according to value of rv$numFields
#
observe({
if(rv$numFields > 1)
{
lapply(2:rv$numFields, function(i) {
output[[paste0("textUI", i)]] <- renderUI({
textInput(paste0("textInput", i), paste0("Input #", i))
})
})
}
})
}
ui <- fluidPage(sidebarLayout(
sidebarPanel(
actionButton("addField", "Add text input box")
),
mainPanel(
# UI output
lapply(1:3, function(i) { # instead of 3 I want something like rv$numFields here
uiOutput(paste0("textUI", i))
})
)
))
shinyApp(ui, server)