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

时间:2019-03-18 06:08:31

标签: r shiny dt

我正在使用R 3.3.1,Shiny v.1.2.0和DT 0.5版开发Shiny应用程序。元素之一是跨多个页面的可编辑数据表。我进行编辑后,焦点所在的行跳到了第一行,这破坏了用户体验。

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

  1. 加载应用
  2. 切换到数据表的第2页
  3. 编辑第3行,第2列:将Duh更改为Blue,然后按Tab键
  4. 观看当前行跳至第1页第1行。这将更容易查看每页是否有更多行。

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

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

看似相关的问题-DataTable doesn't remember paginated page after edit,但在此特定示例中,我不知道如何从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)

2 个答案:

答案 0 :(得分:2)

在这种情况下,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)
    })
  }

答案 1 :(得分:0)

这是我的建议:

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)

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