13

Is it possible to update a reactive data source by editing the DT::DataTable? Below code is based on this code with change that x is made reactive. The problem starts when trying to change x in observeEvent.

The purpose of having x reactive is that I intend to source it from an external database, then have edits to the DT::DataTable write back to the database so that it stays in sync with what the user sees (I'm fine with doing that - it is not part of the question).

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    DTOutput('x1')
  ),
  server = function(input, output, session) {
    x = reactive({
      df <- iris
      df$Date = Sys.time() + seq_len(nrow(df))
      df
    })
    output$x1 = renderDT(x(), selection = 'none', editable = TRUE)

    proxy = dataTableProxy('x1')

    observeEvent(input$x1_cell_edit, {
      info = input$x1_cell_edit
      str(info)
      i = info$row
      j = info$col
      v = info$value

      # problem starts here
      x()[i, j] <<- isolate(DT::coerceValue(v, x()[i, j])) 
      replaceData(proxy, x(), resetPaging = FALSE)  # important
    })
  }
)
Vlad
  • 2,253
  • 3
  • 17
  • 41

2 Answers2

18

I am not sure if I understand you correctly, but maybe this solution might help you a bit. I changed your reactive into a reactiveValues object and I removed the replaceData line.

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    DTOutput('x1'),
    verbatimTextOutput("print")
  ),
  server = function(input, output, session) {
    x = reactiveValues(df = NULL)

    observe({
      df <- iris
      df$Date = Sys.time() + seq_len(nrow(df))
      x$df <- df
    })

    output$x1 = renderDT(x$df, selection = 'none', editable = TRUE)

    proxy = dataTableProxy('x1')

    observeEvent(input$x1_cell_edit, {
      info = input$x1_cell_edit
      str(info)
      i = info$row
      j = info$col
      v = info$value

      # problem starts here
      x$df[i, j] <- isolate(DT::coerceValue(v, x$df[i, j]))
    })

    output$print <- renderPrint({
      x$df
    })
  }
)
SeGa
  • 8,183
  • 3
  • 22
  • 54
  • 1
    I'm having the issue that if you change column 1, info$col actually shows 0. Not sure why i get column numbers that are n -1 in my app. Anyone else seen this? I'll test tomorrow with this dummy app code – Mark Oct 03 '18 at 20:55
  • I have the same problem, but simply adding 1 to col doesn't work either. – Simon Woodward May 20 '19 at 00:10
  • Indeed, this seems to happen when `rownames` are `NULL`, which causes an error when editing the first column and otherwise edits the wrong column. But adding 1 to `j` seems to fix it for me. – SeGa May 20 '19 at 09:25
4

If you don't show the row names in your DT then you should add 1 to info$col to get the correct column i.e., j = info$col + 1.

Tushar Walzade
  • 3,182
  • 4
  • 26
  • 45