Abdallah Atef
Abdallah Atef

Reputation: 671

DT with Shiny: Multipage editable DataTable jumps to first page after an edit

I have the following program. As the title suggests, every time I edit an item on pages after the first page the table goes back to the first page. I'd like the table to stay on the page I'm editing without jumping back to the first page.

I've seen this problem on other threads here but their solutions don't seem to work with current version of DT and shiny packages.

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


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

    output$print <- renderPrint({
      x$df
    })
  }
)

Any help would be appreciated

Upvotes: 2

Views: 937

Answers (2)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84519

You can do like this:

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

    dat <- reactiveVal(cbind(iris, Date = Sys.time() + seq_len(nrow(iris))))

    output$x1 = renderDT(isolate(dat()), selection = 'none', editable = TRUE)

    proxy = dataTableProxy('x1')

    observeEvent(input$x1_cell_edit, {
      info = input$x1_cell_edit
      dat(editData(dat(), info, proxy, resetPaging = FALSE))
    })

    output$print <- renderPrint({
      dat()
    })
  }
)

Upvotes: 4

Eli Berkow
Eli Berkow

Reputation: 2725

Please see DT-edit. I have copied the 2 relevant examples below:

library(shiny)
library(DT)

dt_output = function(title, id) {
    fluidRow(column(
        12, h1(paste0('Table ', sub('.*?([0-9]+)$', '\\1', id), ': ', title)),
        hr(), DTOutput(id)
    ))
}
render_dt = function(data, editable = 'cell', server = TRUE, ...) {
    renderDT(data, selection = 'none', server = server, editable = editable, ...)
}

shinyApp(
    ui = fluidPage(
        title = 'Double-click to edit table cells',

        dt_output('client-side processing (editable = "cell")', 'x1'),
        dt_output('server-side processing (editable = "cell")', 'x5')
    ),

    server = function(input, output, session) {
        d1 = iris
        d1$Date = Sys.time() + seq_len(nrow(d1))
        d5 = d1

        options(DT.options = list(pageLength = 5))

        # client-side processing
        output$x1 = render_dt(d1, 'cell', FALSE)

        observe(str(input$x1_cell_edit))

        # server-side processing
        output$x5 = render_dt(d5, 'cell')

        # edit a single cell
        proxy5 = dataTableProxy('x5')
        observeEvent(input$x5_cell_edit, {
            info = input$x5_cell_edit
            str(info)  # check what info looks like (a data frame of 3 columns)
            d5 <<- editData(d5, info)
            replaceData(proxy5, d5, resetPaging = FALSE)  # important
            # the above steps can be merged into a single editData() call; see examples below
        })

    }
)

I am not sure why you seem to be unnecessarily complicating the process with your reactiveValues but that is probably the cause of your table needing to refresh back to the first page.

Upvotes: 2

Related Questions