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:

shiny dynamic elements example

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

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -

java - Digest auth with Spring Security using javaconfig -