【发布时间】:2022-01-18 01:13:20
【问题描述】:
我有一个闪亮的应用程序,它由几个选定的小部件组成。小部件的数量取决于一些数据。在这个例子中,我使用了两个。但是,用户可以选择通过操作按钮添加或删除选择小部件。
目前无法清除这些选择小部件。例如,打开应用程序并删除第二个选择小部件。之后,添加另一个选择小部件。发生的情况是新的选择小部件仍然具有旧值。但我想要的是新的选择小部件是空的。我尝试使用updateSelectInput() 来实现这一点,但它不起作用。
感谢您的帮助。如果您对如何改进应用程序或使其更简单而不丢失功能有任何建议,我也很乐意听到。
library(shiny)
data <- data.frame(A = c("a", "b"))
ui <- fluidPage(
fluidRow(
column(
width = 6,
uiOutput("ui_output_A")
),
),
fluidRow(
column(
width = 6,
uiOutput("ui_button_add"),
),
column(
width = 6,
uiOutput("ui_button_remove")
)
)
)
server <- function(input, output, session) {
widget_counter <- reactiveValues(value = 1)
if (nrow(data) > 1) {
widget_counter$value <- nrow(data)
} else {
widget_counter$value <- 1
}
output$ui_button_add <- renderUI({
actionButton("button_add",
label = "Add")
})
output$ui_button_remove <- renderUI({
actionButton("button_remove",
label = "Remove")
})
observeEvent(input$button_add, {
widget_counter$value <- widget_counter$value + 1
})
observeEvent(input$button_remove, {
if (widget_counter$value > 0) {
updateSelectInput(
session = session,
inputId = paste0("selectt_A_",
widget_counter$value),
selected = NA
)
widget_counter$value <- widget_counter$value - 1
}
})
all_inputs <- reactive({
x <- reactiveValuesToList(input)
})
reactive_A <- reactive({
n <- widget_counter$value
if (n > 0) {
isolate({
lapply(seq_len(n), function(i) {
selectInput(inputId = paste0("select_A_", i),
label = paste0(i, ".) A:"),
choices = as.list(c("", "a", "b", "c", "d")),
selected =
if (isTRUE(i <= nrow(data))) {
data[i, "A"]
} else {
all_inputs()[[paste0("select_A_", i)]]
}
)
})
})
}
})
output$ui_output_A <- renderUI({reactive_A()})
}
shinyApp(ui, server)
编辑
我对原始帖子中的示例进行了过多的简化,因此这里进行了修改。初始小部件的数量取决于用户选择的表格行。我试图通过将一些代码从 ui 移动到服务器来扩展 lz100 的答案。然而,我失败了。请参阅以下代码。
library(shiny)
library(DT)
library(spsUtil)
data1 <- data.frame(id = c(1, 1, 2),
value = c("a", "b", "a"))
data2 <- data.frame(id = 1:2)
ui <- fluidPage(
fluidRow(
DTOutput("table_output")
),
fluidRow(
column(
width = 6,
uiOutput("ui_output")
)
),
fluidRow(
column(
width = 6,
actionButton("button_add",
label = "Add"),
),
column(
width = 6,
actionButton("button_remove",
label = "Remove")
)
)
)
server <- function(input, output, session) {
counter <- reactiveValues(value = 1)
output$table_output <- renderDT(datatable(data2))
observeEvent(input$table_output_rows_selected, {
if (length(which(data1[, "id"] == data2[input$table_output_rows_selected, "id"])) > 1) {
counter$value <- length(which(data1[, "id"] == data2[input$table_output_rows_selected, "id"]))
} else {
counter$value <- 1
}
})
output$ui_output <- renderUI({
div(
id = "input_els",
# define some default inputs, here 2 default inputs
# when user wants to add more, we do it from server
lapply(seq_len(counter$value), function(i) {
div(
id = paste0("select_container", i),
selectInput(paste0("select_", i),
label = paste0(i, ".):"),
choices = as.list(c("", letters)),
selected =
if (isTRUE(i <= length(which(data1[, "id"] == data2[input$table_output_rows_selected, "id"])))) {
data1[i, "value"]
} else {
NA
}
)
)
})
)
})
observeEvent(input$button_add, {
insertUI(
"#input_els",
ui = div(
id = paste0("select_container", counter$value + 1),
selectInput(
paste0("select_", counter$value + 1),
paste0(counter$value + 1, ".) "),
c("", "a", "b", "c", "d")
)
)
)
inc(counter$value)
})
observeEvent(input$button_remove, {
req(counter$value > 0)
removeUI(paste0("#select_container", counter$value))
inc(counter$value, -1)
})
}
shinyApp(ui, server)
【问题讨论】: