Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Shiny Destroy ObserveEvent

Tags:

r

shiny

I am new to R Shiny. I am trying to create an app with some dynamically generated buttons. Each button has a observeEvent associated with it. I want to add a reset button which deletes all the observeEvents. I went through some links and found that destroy() function can be used for the same, but I am unable to figure out how to use it. Any suggestions? Thanks.

library(shiny)
ui<-fluidPage(
  actionButton(inputId = "add",label = "Add Stuff"),
  htmlOutput("obs"),
  actionButton("reset","Reset")
)
server<-function(input,output,session){

  output$obs<-renderUI(HTML({names(input)}))

  observeEvent(input$add,{
    addModal<-function(failed=FALSE){

      modalDialog(size = "l",easyClose = T,title = "Add",footer = "",
                  selectInput(inputId = "stuff",label = "Select",choices = c("A","B","C","D","E")),
                  numericInput(inputId = "numstuff",label = "Quantity",min = 1,max = 5,value = 1),
                  actionButton(inputId = "add2",label = "Add")
                  )

    }
    showModal(addModal())
  })

  num<<-0
  observeEvent(input$add2,{
    num<<-num+1
    insertUI(selector = "#add",where = "beforeBegin",
             ui = actionButton(inputId = paste0("comp",num),label = paste0(input$stuff,":",input$numstuff))
    )
    lapply(num:num,function(i){
    observeEvent(input[[paste0("comp",i)]],{
      modModal<-function(failed=FALSE){

        modalDialog(size = "l",easyClose = T,title = "Delete",footer = "",
                    # numericInput(inputId = "newquan",label = "New Quantity",min=1,max=5,value=1),
                    actionButton(inputId = paste0("gomod",i),label = "Delete")
        )
      }
      showModal(modModal())
    },ignoreInit = T)

    observeEvent(input[[paste0("gomod",i)]],{
      nm<-paste0("#comp",i)
      removeUI(selector=nm)
    })

  })
  })

  observeEvent(input$reset,{
    observers<-names(input)
    lapply(observers,function(x){
      if(substr(x,1,4)=="comp"){
        obs<-input[[x]]
        obs$destroy()
      }
    })
  })

}
shinyApp(ui=ui,server=server)
like image 290
Ayush Avatar asked Jun 05 '17 10:06

Ayush


1 Answers

You have to assign the observe (or observeEvent) to a variable (e.g. o) and then call o$destroy inside the body of the observer. See this app for a good example of using this (though the use case, which is to create "concurrent, forked, cancellable tasks in Shiny," is probably a lot more complicated than yours). In any case, you can see the mechanism in action there.

You may also be interested in this app, which I think accomplishes what you want in an easier way (using the once = TRUE argument).

like image 102
Bárbara Borges Avatar answered Sep 21 '22 13:09

Bárbara Borges