简体   繁体   中英

Access updated DataTable edited with CellEdit in R shiny

I used CellEdit callback to create dropdown selectors in my shiny DataTable. So far, I am not able to retrieve the updated values by making the event table_cell_edit work. I have already spent hours on this without success, could anyone help? I am not very familiar with javascript and I am not sure where the problem comes from.

Here is the code I used:

  • Before ui/server
callback = JS(
  "function onUpdate(updatedCell, updatedRow, oldValue){}",
  "table.MakeCellsEditable({",
  "  onUpdate: onUpdate,",
  "  inputCss: 'my-input-class',",
  "  columns : [0,1,2,3],",
  "  confirmationButton: {",
  "    confirmCss: 'my-confirm-class',",
  "    cancelCss: 'my-cancel-class'",
  "  },",
  "  inputTypes: [",
  "    {",
  "      column: 0,",
  "      type: 'list',",
  "      options: [",
  "        {value: ' ', display: ' '},",
  "        {value: 'yes',      display: 'yes'},",
  "        {value: 'no',    display: 'no'}",
  "      ]",
  "    },",
  "    {",
  "      column: 2,",
  "      type: 'list',",
  "      options: [",
  "        {value: ' ', display: ' '},",
  "        {value: 'yes',      display: 'yes'},",
  "        {value: 'no',    display: 'no'}",
  "      ]",
  "    }",
  "  ]",
  "});")

path <- file.path("./src/app/") # folder containing the files dataTables.cellEdit.js
# and dataTables.cellEdit.css
dep <- htmltools::htmlDependency(
  "CellEdit", "1.0.19", path, 
  script = "dataTables.cellEdit.js", stylesheet = "dataTables.cellEdit.css")
  • server:

     output$table <- DT::renderDT({ dtable <- DT::datatable( reactivedf(), container = sketch, filter="top", extensions = c("Buttons","FixedHeader","Scroller"), rownames=FALSE, options = list(#dom = 'Bfrtip', pageLength = nrow(reactivedf()), columnDefs = list( list(targets = "_all", className = "dt-center")), scroller=TRUE, scrollX=TRUE, scrollY="500px" ), editable = list(target = 'cell', disable = list(columns = c(4:31))), callback = JS(callback), selection='none' ) dtable$dependencies <- c(dtable$dependencies, list(dep)) dtable }, server=F) observeEvent(input$table_cell_edit, { print("let's try") new_df <- reactivedf() row <- input$table_cell_edit$row col <- input$table_cell_edit$col value <- as.numeric(input$table_cell_edit$value) new_df[row, col] <- value reactivedf(new_df) })

You have to use the callback function onUpdate .

First, get the id of the datatable:

  "var tbl = $(table.table().node());",
  "var id = tbl.closest('.datatables').attr('id');",

Then:

  "function onUpdate(updatedCell, updatedRow, oldValue) {",
  "  var cellinfo = [{",
  "    row: updatedCell.index().row + 1,",
  "    col: updatedCell.index().column + 1,",
  "    value: updatedCell.data()",
  "  }];",
  "  Shiny.setInputValue(id + '_cell_edit:DT.cellInfo', cellinfo);",
  "}",

Here is a complete, minimal example:

library(shiny)
library(DT)

callback <- c(
  "var tbl = $(table.table().node());",
  "var id = tbl.closest('.datatables').attr('id');",
  "function onUpdate(updatedCell, updatedRow, oldValue) {",
  "  var cellinfo = [{",
  "    row: updatedCell.index().row + 1,",
  "    col: updatedCell.index().column + 1,",
  "    value: updatedCell.data()",
  "  }];",
  "  Shiny.setInputValue(id + '_cell_edit:DT.cellInfo', cellinfo);",
  "}",
  "table.MakeCellsEditable({",
  "  onUpdate: onUpdate,",
  "  inputCss: 'my-input-class',",
  "  confirmationButton: {",
  "    confirmCss: 'my-confirm-class',",
  "    cancelCss: 'my-cancel-class'",
  "  },",
  "  inputTypes: [",
  "    {",
  "      column: 0,",
  "      type: 'list',",
  "      options: [",
  "        {value: 'Keep data', display: 'Keep data'},",
  "        {value: 'Pass', display: 'Pass'},",
  "        {value: 'Delete', display: 'Delete'}",
  "      ]",
  "    }",
  "  ]",
  "});"
)

ui <- fluidPage(
  br(),
  DTOutput("dt"),
  br(),
  verbatimTextOutput("editedCell")
)

server <- function(input, output, session){
  
  dat <- data.frame(
    Action = c("Keep data", "Pass", "Delete"),
    X = c(1, 2, 3),
    Y = c("a", "b", "c")
  )
  
  output[["dt"]] <- renderDT({
    dtable <- datatable(dat, 
                        rownames = FALSE,
                        selection = "none",
                        callback = JS(callback)
    )
    path <- path.expand("www") # folder containing the files dataTables.cellEdit.js
                               # and dataTables.cellEdit.css
    dep <- htmltools::htmlDependency(
      "CellEdit", "1.0.19", path, 
      script = "dataTables.cellEdit.js", stylesheet = "dataTables.cellEdit.css", 
      all_files = FALSE)
    dtable$dependencies <- c(dtable$dependencies, list(dep))
    dtable
  }, server = FALSE)
  
  output[["editedCell"]] <- renderPrint({
    input[["dt_cell_edit"]]
  })  
}

shinyApp(ui, server)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM