r - Dynamically add and remove uiOutput elements based on index using actionButtons -
i'm trying add , remove uioutput
elements using index keep track of each individual element. there actionbutton
adding , element list, , x button each element removes selected item, in image below:
i'm using single .rmd file includes both ui
, server
code. current solution (with cannot produce desired functionality shown above---it nothing) following:
actionbutton("addfilter", "add filter", icon=icon("plus", class=null, lib="font-awesome")) <- 0 observeevent(input$addfilter, { <<- + 1 uioutput(paste("filterpage",i,sep="")) output[[paste("filterpage",i,sep="")]] = renderui({ fluidpage( fluidrow( column(6, selectinput(paste("filteringfactor",i,sep=""), "choose factor 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 put uioutput
, remove-button observeevent
outside of add-button observeevent
code works, need have separate statement per index, 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")) <- 0 observeevent(input$addfilter, { <<- + 1 output[[paste("filterpage",i,sep="")]] = renderui({ fluidpage( fluidrow( column(6, selectinput(paste("filteringfactor",i,sep=""), "choose factor 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 loop or lapply
call work (it looks scoping problem not understand). number of elements not known in advance hardcoding values not work me. know how make work? thanks.
i have fix you, might not beautiful on backend, makes life easy. i'd suggest nest elements within each other. make uioutput
number i
contain uioutput
next one. way, can add them successively without needing worry size or total number of elements. performance-wise okay, since don't think creating thousands of filters. see code more details.
for deleting, have seen it's tedious keep track of button input values. i'd suggest design 1 variable observe, tells element number, has been clicked. can achieve custom onclick
function our buttons, sending button number 1 single input variable. might want make familiar javascript client function shiny.oninputchange
. briefly: sends value r backend under given variable name.
deleting corresponding ui element easy.
if want more , design more clear, more fine solution, try this page , related questions. there can input on how design , add chunks of dynamic ui document without commonly used single uioutput
wrapper.
code below (i made regular ui-server app):
library(shiny) ui <- shinyui( fluidpage( actionbutton("addfilter", "add filter", icon=icon("plus", class=null, lib="font-awesome")), uioutput("filterpage1") ) ) server <- function(input, output){ <- 0 observeevent(input$addfilter, { <<- + 1 output[[paste("filterpage",i,sep="")]] = renderui({ list( fluidpage( fluidrow( column(6, selectinput(paste("filteringfactor",i,sep=""), "choose factor 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"), onclick = paste0("shiny.oninputchange('remove', ", i, ")"))) ) ), uioutput(paste("filterpage",i + 1,sep="")) ) }) }) observeevent(input$remove, { <- input$remove output[[paste("filterpage",i,sep="")]] <- renderui({uioutput(paste("filterpage",i + 1,sep=""))}) }) } shinyapp(ui, server)
Comments
Post a Comment