R Shiny - 多页可编辑数据表在编辑后跳转到第 1 行

R Shiny - multi-page editable DataTable jumps to row #1 after an edit

我正在使用 R 3.3.1、Shiny v. 1.2.0 和 v. DT 0.5 开发一个 Shiny 应用程序。其中一个元素是跨越多个页面的 editable 数据 table。在我进行编辑后,焦点行跳转到第 1 行,这会破坏用户体验。

以下是使用以下代码段重现此内容的具体步骤:

  1. 加载应用程序
  2. 切换到数据的第2页table
  3. 编辑第 3 行第 2 列:将 Duh 更改为 Blue 并按 Tab
  4. 观察当前行跳转到第 1 页第 1 行。如果每页有更多行,这将更容易查看。

我在第 4 步中得到的不是理想的行为。我希望数据 table 将焦点放在我刚刚编辑的同一行上。

我愿意使用自定义 JS 逻辑来完成这项工作。

看似相关的问题 - 但我不知道如何在这个特定示例中从 R 桥接到 JS。

 R.version.string
# "R version 3.3.1 (2016-06-21)"

library(shiny)  # v. 1.2.0
library(DT)  # v. 0.5

page_length <- 2 # 5 elements should span 3 pages

hardcoded_df <- read.table(text = "Fruit Color
                                   Apple Red
                                   Plum Purple
                                   Blueberry Duh
                                   Orange Carrot
                                   Crocodile Green",
                           header = TRUE,
                           stringsAsFactors = FALSE)

ui <- fluidPage(
   DT::dataTableOutput('x1')
)

server <- function(input, output) {
  x = reactiveValues(df = hardcoded_df)

   output$x1 = renderDT(DT::datatable(x$df, options = list(pageLength = page_length), selection = 'none', editable = TRUE))

   proxy = dataTableProxy('x1')

   observeEvent(input$x1_cell_edit, {
     info = input$x1_cell_edit
     str(info)

     # str(input$x1_state)
     i = info$row
     j = info$col
     v = info$value

     # Without this line the table does not change but with it it jumps to row 1 after an edit.
     x$df[i, j] <- isolate(DT::coerceValue(v, x$df[i, j]))

     # Now we need to scroll to row i somehow ... clearly this does not work. Help!
     selectPage(proxy, ceiling(i / page_length))
     # selectRow(proxy, i)
   })
}

# Run the application 
shinyApp(ui = ui, server = server)

这是我的提议:

server <- function(input, output) {
  x = reactiveValues(df = hardcoded_df)

  output$x1 = renderDT(DT::datatable(x$df, options = list(pageLength = page_length), selection = 'none', editable = TRUE))

  observeEvent(input$x1_cell_edit, {
    info = input$x1_cell_edit
    str(info)

    # str(input$x1_state)
    i = info$row
    j = info$col
    v = info$value

    # Without this line the table does not change but with it it jumps to row 1 after an edit.
    proxy = dataTableProxy('x1')
    newdf <-  x$df
    newdf[i,j] <- coerceValue(v, newdf[i, j])
    print(newdf)
    replaceData(proxy, newdf,resetPaging = F)

    # selectRow(proxy, i)
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

我不确定这是否是最干净的方法,但这是我能做到的最好的方法。

在这种情况下,DT::replaceDataresetPaging = FALSE 应该可以正常工作,如图 here 所示。但是,将 x 定义为 reactiveValues() 会导致一些问题,我使用 isolate

解决了这些问题
 server <- function(input, output, session) {
    x = reactiveValues(df = hardcoded_df)
    output$x1 = renderDT(DT::datatable(isolate(x$df), 
                options = list(pageLength = page_length), selection = 'none', editable = TRUE))

    proxy = dataTableProxy('x1')

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

      # Without this line the table does not change but with it it jumps to row 1 after an edit.
      x$df[i, j] <- isolate(DT::coerceValue(v, x$df[i, j]))
      DT::replaceData(proxy, x$df, resetPaging = FALSE)  # important
      # Now we need to scroll to row i somehow ... clearly this does not work. Help!
      #selectPage(proxy, ceiling(i / page_length))
      # selectRow(proxy, i)
    })
  }