I'm trying to add and remove uiOutput
elements using an index to keep track of each individual element. There is an actionButton
for adding and element to the list, and an x button for each element that removes the selected item, as in the image below:
I'm using a single .Rmd file that includes both ui
and server
code. My current solution (with which I cannot produce the desired functionality shown above---it basically does nothing) is the following:
actionButton("addFilter", "Add filter", icon=icon("plus", class=NULL, lib="font-awesome"))
i <- 0
observeEvent(input$addFilter, {
i <<- i + 1
uiOutput(paste("filterPage",i,sep=""))
output[[paste("filterPage",i,sep="")]] = renderUI({
fluidPage(
fluidRow(
column(6, selectInput(paste("filteringFactor",i,sep=""), "Choose factor to filter by:",
choices=c("factor A", "factor B", "factor C"), selected="factor B",
width="100%")),
column(6, actionButton(paste("removeFactor",i,sep=""), "",
icon=icon("times", class = NULL, lib = "font-awesome")))
)
)
})
observeEvent(input[[paste("removeFactor",i,sep="")]], {
output[[paste("filterPage",i,sep="")]] = renderUI({})
})
})
When I put uiOutput
and the remove-button observeEvent
outside of the add-button observeEvent
the code works, but I need to have a separate statement per index, as follows:
uiOutput(paste("filterPage",1,sep=""))
uiOutput(paste("filterPage",2,sep=""))
uiOutput(paste("filterPage",3,sep=""))
uiOutput(paste("filterPage",4,sep=""))
actionButton("addFilter", "Add filter", icon=icon("plus", class=NULL, lib="font-awesome"))
i <- 0
observeEvent(input$addFilter, {
i <<- i + 1
output[[paste("filterPage",i,sep="")]] = renderUI({
fluidPage(
fluidRow(
column(6, selectInput(paste("filteringFactor",i,sep=""), "Choose factor to filter by:",
choices=c("factor A", "factor B", "factor C"), selected="factor B",
width="100%")),
column(6, actionButton(paste("removeFactor",i,sep=""), "",
icon=icon("times", class = NULL, lib = "font-awesome")))
)
)
})
})
observeEvent(input[[paste("removeFactor",1,sep="")]], {
output[[paste("filterPage",1,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",2,sep="")]], {
output[[paste("filterPage",2,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",3,sep="")]], {
output[[paste("filterPage",3,sep="")]] = renderUI({})
})
observeEvent(input[[paste("removeFactor",4,sep="")]], {
output[[paste("filterPage",4,sep="")]] = renderUI({})
})
I couldn't make a for loop or lapply
call to work (it looks like a scoping problem I do not understand). As the number of elements is not known in advance hardcoding the values will not work for me. Does anybody know how to make this work? Thanks.