Home > Net >  ShinyApp: keep dynamically generated input values from being lost
ShinyApp: keep dynamically generated input values from being lost

Time:02-02

I have some inputs that are generated or eliminated if some actionButtons are activated. However, the input value is reset each time any actionButton is activated. I know this is because the inputs are rendered each time one of the actionButton are pressed. So is there a way to get a hold of the values selected? I though of render each on his own uiOutput, but I don't know how to do that dynamically as in this approach. That or any other implementation is greatly appreciated.

Reprex:

library(shiny)

ui <- fluidPage(
  actionButton("addInput", "Agregar"),
  actionButton("removeInput", "Eliminar"),
  uiOutput("inputs"),
  h3("When you select any value from any input and then press an actionButton, the values are lost because the inputs are rendered once again. How can I keep the values selected even after adding or deletion of a new input?")
)

server <- function(input, output, session) {
  
  i <- reactive({
    i <- input$addInput - input$removeInput
    if(i <= 0 ){
    i <- 1 }
    return(i)
  })
  
  output$inputs <- renderUI({
    if (is.null(i())) return(NULL)
    tagList(
      lapply(1:i(),function(j){
        
    shiny::selectInput(paste0('vble_',i()[j]), '', choices = c(LETTERS))
      })
    )
  })
}

shinyApp(ui, server)

CodePudding user response:

One way to do it is using insertUI and removeUI. Try this

library(shiny)

ui <- fluidPage(
  actionButton("addInput", "Agregar"),
  actionButton("removeInput", "Eliminar"),
  #uiOutput("inputs"),
  tagList(tags$div(id = 'placeholder')),
  h3("When you select any value from any input and then press an actionButton, the values are lost because the inputs are rendered once again. How can I keep the values selected even after adding or deletion of a new input?")
)

server <- function(input, output, session) {
  numvars <- reactiveVal(0)
  i <- reactive({
    i <- input$addInput - input$removeInput
    if(i <= 0 ){ i <- 1 }
    return(i)
  })
  
  ### keep track of elements/lines inserted and not yet removed
  inserted <- c()
  
  observeEvent(input$addInput,{
    if (numvars()<0) {
      numvars(0)  #  clicking on remove button too many times yields negative number; reset it to one
    }
    
    newValue <- numvars()   1     
    numvars(newValue)             
    # btn needs to be adjusted if removing and adding 
    if (input$removeInput==0){
      btn <- input$addInput
    }else {
      if (input$addInput > input$removeInput) {
        btn <- input$addInput - input$removeInput  #  addInput counter does not decrease
      }else btn <- numvars()
    } 
    
    id <- paste0('txt', btn)
    
    insertUI(
      selector = '#placeholder',
      ## wrap element in a div with id for ease of removal
      ui = tags$div(
        div(    
            shiny::selectInput(paste0('vble_',btn), '', choices = c(LETTERS))  
        ),
        id = id
      )
    )
    inserted <<- c(inserted, id)  ##  removes last one first
    
    #print(numvars())
    #print(inserted)
    
  })
  
  observeEvent(input$removeInput,{
    newValue <- numvars() - 1     
    numvars(newValue)  
    if (newValue<0) numvars(0)
    
    if (numvars()>0){
      removeUI(
        ## pass in appropriate div id
        selector = paste0('#', inserted[length(inserted)])
      )
      inserted <<- inserted[-length(inserted)]
    }else inserted <<- c()
  })

}

shinyApp(ui, server)
  •  Tags:  
  • Related