ShinyApp:防止动态生成的输入值丢失
ShinyApp: keep dynamically generated input values from being lost
如果某些 actionButtons
被激活,我有一些输入会生成或消除。但是,每次激活任何 actionButton
时都会重置输入值。我知道这是因为每次按下 actionButton
之一时都会呈现输入。那么有没有办法掌握所选的值呢?我虽然自己渲染每个 uiOutput
,但我不知道如何像这种方法那样动态地做到这一点。非常感谢该实现或任何其他实现。
代表:
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)
一种方法是使用 insertUI
和 removeUI
。试试这个
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)
如果某些 actionButtons
被激活,我有一些输入会生成或消除。但是,每次激活任何 actionButton
时都会重置输入值。我知道这是因为每次按下 actionButton
之一时都会呈现输入。那么有没有办法掌握所选的值呢?我虽然自己渲染每个 uiOutput
,但我不知道如何像这种方法那样动态地做到这一点。非常感谢该实现或任何其他实现。
代表:
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)
一种方法是使用 insertUI
和 removeUI
。试试这个
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)