我正在开发R Shiny应用程序,用户可以控制数据表。他们可以向表中添加新行,或删除任何现有行。我的愿望是在表格中嵌入一个“删除”按钮,用户可以单击该按钮,然后将删除该行。
以下是我的解决方案的当前状态,但是并不能始终如一地工作。 “添加”按钮始终工作,但是有时无法识别“删除”按钮。
```
library(DT)
getRemoveButtons <- function(n, idS = "", lab = "Pit") {
if (stringr::str_length(idS) > 0) idS <- paste0(idS, "-")
ret <- shinyInput(actionButton, n,
'button_', label = "Remove",
onclick = sprintf('Shiny.onInputChange(\"%sremove_button_%s\", this.id)' ,idS, lab))
return (ret)
}
shinyInput <- function(FUN, len, id, ses, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), ...))
}
inputs
}
ui = shinyUI(fluidPage(
fluidRow(DT::dataTableOutput("myTable")),
fluidRow(actionButton("addRow", label = "Add Row",
icon = icon("plus"))))
)
server = function(input, output) {
values <- reactiveValues()
values$tab <- tibble(
Row = 1:3L,
Remove = getRemoveButtons(3, idS = "", lab = "Tab1"))
proxyTable <- DT::dataTableProxy("tab")
output$myTable <- DT::renderDataTable({
DT::datatable(values$tab,
options = list(pageLength = 25,
dom = "rt"),
rownames = FALSE,
escape = FALSE,
editable = TRUE)
})
observeEvent(input$remove_button_Tab1, {
myTable <- values$tab
s <- as.numeric(strsplit(input$remove_button_Tab1, "_")[[1]][2])
myTable <- filter(myTable, row_number() != s)
myTable <-
mutate(myTable,
Remove = getRemoveButtons(nrow(myTable), idS = "", lab = "Tab1"))
replaceData(proxyTable, myTable, resetPaging = FALSE)
values$tab <- myTable
})
observeEvent(input$addRow, {
myTable <- isolate(values$tab)
myTable <- select(myTable, Row)
myTable <- bind_rows(
myTable,
tibble(Row = nrow(myTable) + 1))
myTable <- mutate(myTable,
Remove = getRemoveButtons(nrow(myTable), idS = "", lab = "Tab1"))
replaceData(proxyTable, myTable, resetPaging = FALSE)
values$tab <- myTable
})
}
shinyApp(ui = ui, server = server)
答案 0 :(得分:2)
好的,我现在可以正常工作了。问题是试图为按钮重复使用ID。通过创建一个计数器并为每个新按钮分配一个从未使用过的ID,现在它可以完美工作了。修改后的代码如下。
```
library(DT)
library(dplyr)
getRemoveButton <- function(n, idS = "", lab = "Pit") {
if (stringr::str_length(idS) > 0) idS <- paste0(idS, "-")
ret <- shinyInput(actionButton, n,
'button_', label = "Remove",
onclick = sprintf('Shiny.onInputChange(\"%sremove_button_%s\", this.id)' ,idS, lab))
return (ret)
}
shinyInput <- function(FUN, n, id, ses, ...) {
as.character(FUN(paste0(id, n), ...))
}
ui = shinyUI(fluidPage(
fluidRow(DT::dataTableOutput("myTable")),
fluidRow(actionButton("addRow", label = "Add Row",
icon = icon("plus"))))
)
server = function(input, output) {
buttonCounter <- 3L
values <- reactiveValues()
values$tab <- tibble(
Row = 1:3L,
id = 1:3L) %>%
rowwise() %>%
mutate(Remove = getRemoveButton(id, idS = "", lab = "Tab1"))
proxyTable <- DT::dataTableProxy("tab")
output$myTable <- DT::renderDataTable({
DT::datatable(values$tab,
options = list(pageLength = 25,
dom = "rt"),
rownames = FALSE,
escape = FALSE,
editable = TRUE)
})
observeEvent(input$remove_button_Tab1, {
myTable <- values$tab
s <- as.numeric(strsplit(input$remove_button_Tab1, "_")[[1]][2])
myTable <- filter(myTable, id != s)
replaceData(proxyTable, myTable, resetPaging = FALSE)
values$tab <- myTable
})
observeEvent(input$addRow, {
buttonCounter <<- buttonCounter + 1L
myTable <- isolate(values$tab)
myTable <- bind_rows(
myTable,
tibble(Row = nrow(myTable) + 1) %>%
mutate(id = buttonCounter,
Remove = getRemoveButton(buttonCounter, idS = "", lab = "Tab1")))
replaceData(proxyTable, myTable, resetPaging = FALSE)
values$tab <- myTable
})
}
shinyApp(ui = ui, server = server)