In R Shiny, I am able to add additional input fields with an actionButton, using this technique: R Shiny: How to create an "Add Field" Button (call it Section A). Now I want to allow users to add additional input fields within Section A. Basically, I want to nest “Add an Input” within “Add an Input”.
I made a mockup app using the example in the quoted thread. For this particular example, the goal is to allow users to add multiple comments by hitting the "Add Comment" button under each textbox that they have created using the "Add Text" button.
However, with observeEvent({}) nested, I got an error: Error in as.vector: cannot coerce type 'environment' to vector of type 'character'.
ui <- shinyUI(fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(
actionButton("addText","Add Text"),
uiOutput("txtOutput"),
actionButton("getTexts","Get Input Values")
),
# Show a plot of the generated distribution
mainPanel(
verbatimTextOutput("txtOut"),
verbatimTextOutput("cmtOut")
)
)))
server <- shinyServer(function(input,output,session){
ids <<- NULL
observeEvent(input$addText,{
if (is.null(ids)){
ids <<- 1
}else{
ids <<- c(ids, max(ids)+1)
}
idsa <<- NULL
output$txtOutput <- renderUI({
lapply(1:length(ids),function(i){
textInput(paste0("txtInput",ids[i]), sprintf("Text Input #%d",ids[i]))
uiOutput(outputId = paste0("cmtOutput", ids[i]))
actionButton(inputId = paste0("addComment", ids[i]), "Add Comment")
observeEvent(input[[paste0("addComment",ids[i])]],{
if (is.null(idsa)){
idsa <<- 1
}else{
idsa <<- c(idsa, max(idsa)+1)
}
output[[paste0("cmtOutput",ids[i])]] <- renderUI({
lapply(1:length(idsa), function(i){
textInput(paste0("cmtInput", ids[i], "_", idsa[i]), sprintf("Comment Input #%d", idsa[i]))
})
})
})
})
})
})
observeEvent(input$getTexts,{
if(is.null(ids)){
output$txtOut <- renderPrint({"No textboxes"})
output$cmtOut <- renderPrint({"No comments"})
}else{
txtOut <- list()
# Get ids for textboxes
txtbox_ids <- sapply(1:length(ids),function(i){
paste0("txtInput",ids[i],sep="")
})
# Get values
for(i in 1:length(txtbox_ids)){
txtOut[[i]] <- sprintf("Txtbox #%d has value: %s",i,input[[ txtbox_ids[i] ]])
}
output$txtOut <- renderPrint({txtOut})
if(is.null(idsa)){
output$cmtOut <- renderPrint({"No comments"})
}else{
cmtOut <- list()
# Get ids for textboxes
cmtbox_ids <- sapply(1:length(idsa),function(i){
paste0("cmtInput",ids[i], "_", idsa[i],sep="")
})
# Get values
for(i in 1:length(cmtbox_ids)){
cmtOut[[i]] <- sprintf("Comment box #%d has value: %s",i,input[[ cmtbox_ids[i] ]])
}
output$cmtOut <- renderPrint({cmtOut})
}
}
})
})
shinyApp(ui=ui,server=server)