R Shiny删除按钮进入数据表并不能很好地工作

时间:2015-11-05 09:08:17

标签: r shiny action-button

我已经构建了一个闪亮的应用程序,允许用户更新表格中的数据表。 我有一个功能允许用户通过在渲染的数据表中单击actionLink来删除数据中的行。

它运作正常,但我管理了一些错误。当所有删除一次的数据表,并且我放入新条目时,第一个新条目是不可删除的,而不先删除另一行。

这里要明确的是显示错误的步骤:

  1. 添加文本输入并将其添加到数据表
  2. 删除输入
  3. 添加新文字输入
  4. 尝试删除它
  5. 添加其他文字输入
  6. 删除第二个新输入
  7. 删除第一个输入
  8. 我不明白为什么,我认为它来自反应值,但我把observ事件放在可能出现的唯一两个事件上。

    以下是查看错误的可重现示例:

    library(shiny)
    library(DT)
    library(shinydashboard)
    library(shinyjs)
    
    
    
    # ----- function which create the button into the table
    shinyInput <- function(FUN, len, id, ...) {
      inputs <- len
      for (i in seq(len)) {
        inputs[i] <- as.character(FUN(paste0(id, len[i]), ...))
      }
      inputs
    }
    
    # ----- character form vector
    fields<-c("text")
    
    
    ui<-shinyUI(bootstrapPage(
      shinyjs::useShinyjs(),
      title = "Update form",
      fluidRow(
        sidebarPanel(width=2,
                     title = "Submit form", id = "submitTab", value = "submitTab",
                     textInput("text", "Text Input", ""),
                     actionButton("submit", "Add", class = "btn-primary",icon=icon("table"))
                     #     verbatimTextOutput("test")
        ),
        mainPanel(dataTableOutput("data_table")))
    
    ))
    
    server<-shinyServer(function(input, output) {  
    # ----- create the reactive value  
      v<-reactiveValues(data=NULL)  
    
    # ----- when Add button is clicked
      observeEvent(input$submit, {
        dat <- sapply(fields, function(x) input[[x]])
        dat<-data.frame(t(dat),stringsAsFactors=F)
        if(!(is.null(v$data)) && (input$text%in%v$data$text==F)) {
          v$data <- rbind(v$data[,-2], dat)
        } else if(!is.null(v$data) && (input$text%in%v$data$text==T)) {
          indice<-which(v$data$text==input$text)
          v$data[indice,-2] <- dat
        } else {
          v$data<-dat
        }
        v$data<-data.frame(v$data[,-2],Delete = shinyInput(actionLink, rownames(v$data), 'button_',class="btn btn-delete",icon=icon("minus-circle"),label="",onclick = 'Shiny.onInputChange(\"select_button\",  this.id)' ))
      })
    
    # ----- When Delete table button is clicked 
      observeEvent(input$select_button, {
        #     dat<-v$data
        selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])    
        #     dat <- dat[rownames(dat) != selectedRow, ] 
        v$data<-v$data[rownames(v$data)!=selectedRow,]
        v$data<-data.frame(v$data[,-2],Delete = shinyInput(actionLink, rownames(v$data), 'button_',class="btn btn-delete",icon=icon("minus-circle"),label="",onclick = 'Shiny.onInputChange(\"select_button\",  this.id)' ))
      })
    
    # ----- Render the data table
      output$data_table <- renderDataTable(server = TRUE,escape=F,extensions = 'TableTools',options = list(pageLength = 10),{
        if (is.null(v$data)) return()
        v$data
      })  
    })
    
    shinyApp(ui,server)
    

1 个答案:

答案 0 :(得分:2)

嗨我认为第4步的问题是input$select_button的值没有改变,将this.id的时间粘贴似乎已经修复了。看看下面的代码(我做了一些其他改动):

library(shiny)
library(DT)
library(shinydashboard)
library(shinyjs)



# ----- function which create the button into the table
shinyInput <- function(FUN, len, id, ...) {
  inputs <- len
  for (i in seq(len)) {
    inputs[i] <- as.character(FUN(paste0(id, len[i]), ...))
  }
  inputs
}

# ----- character form vector
fields<-c("text")


ui<-shinyUI(bootstrapPage(
  shinyjs::useShinyjs(),
  title = "Update form",
  fluidRow(
    sidebarPanel(width=2,
                 title = "Submit form", id = "submitTab", value = "submitTab",
                 textInput("text", "Text Input", ""),
                 actionButton("submit", "Add", class = "btn-primary",icon=icon("table"))
                 #     verbatimTextOutput("test")
    ),
    mainPanel(dataTableOutput("data_table"), verbatimTextOutput("test")))

))

server<-shinyServer(function(input, output) {  
  # ----- create the reactive value  
  v<-reactiveValues(data=NULL)  

  # ----- when Add button is clicked
  observeEvent(input$submit, {
    dat <- sapply(fields, function(x) input[[x]])
    dat<-data.frame(V1 = dat,stringsAsFactors=F)
    if(!(is.null(v$data)) && (!input$text %in% v$data$text)) {
      v$data <- rbind(data.frame(V1 = as.character(v$data[,1])), dat)
      rownames(v$data) <- seq_len(nrow(v$data))
    } else if(!is.null(v$data) && (input$text %in% v$data$text)) {
      indice<-which(v$data$text==input$text)
      v$data[indice,-2] <- dat
    } else {
      v$data<-dat
    }
    v$data<-data.frame(V1 = v$data[,-2],
                       Delete = shinyInput(actionLink, 
                                       rownames(v$data), 
                                       'button_',
                                       class="btn btn-delete",
                                       icon=icon("minus-circle"),
                                       label="",
                                       onclick = 'Shiny.onInputChange(\"select_button\",  (this.id + \"@\" + Date()))' ))
  })

  # ----- When Delete table button is clicked 
  observeEvent(input$select_button, {
    #     dat<-v$data
    input_button <- gsub(pattern = "@.*", replacement = "", x = input$select_button)
    selectedRow <- as.numeric(strsplit(input_button, "_")[[1]][2])    
    #     dat <- dat[rownames(dat) != selectedRow, ] 
    v$data <- v$data[!rownames(v$data) %in% selectedRow,]
    if (nrow(v$data) > 0) {
      v$data<-data.frame(V1 = v$data[,-2],
                         Delete = shinyInput(actionLink,  
                                         rownames(v$data), 
                                         'button_',
                                         class="btn btn-delete",
                                         icon=icon("minus-circle"),
                                         label="",
                                         onclick = 'Shiny.onInputChange(\"select_button\",  (this.id + \"@\" + Date()))' ))
    }
  })
  output$test <- renderPrint({input$select_button})
  # ----- Render the data table
  output$data_table <- renderDataTable(server = TRUE,escape=F,extensions = 'TableTools',options = list(pageLength = 10),{
    if (is.null(v$data)) return()
    v$data
  })  
})

shinyApp(ui,server)