R Shiny - многостраничный редактируемый DataTable переходит на строку № 1 после редактирования - PullRequest
3 голосов
/ 18 марта 2019

Я занимаюсь разработкой приложения Shiny с использованием R 3.3.1, Shiny v. 1.2.0 и v. DT 0.5. Одним из элементов является редактируемая таблица данных, которая занимает несколько страниц. После того, как я произвожу редактирование, строка в фокусе переходит к строке # 1, которая разрушает работу пользователя.

Вот конкретные шаги, чтобы воспроизвести это, используя фрагмент ниже:

  1. Загрузить приложение
  2. Перейти на страницу 2 таблицы данных
  3. Редактировать строку 3, столбец 2: изменить Duh на синий и нажать Tab
  4. Наблюдайте, как текущая строка переходит к строке 1 страницы 1. Это было бы легче увидеть, если бы на странице было гораздо больше строк.

То, что я получаю на шаге 4, не является желательным поведением. Я хочу, чтобы таблица данных сохраняла фокус на той же строке, которую я только что отредактировал.

Я открыт для использования собственной логики JS для этой работы.

Кажущийся связанным вопрос - DataTable не помнит страницу с нумерацией страниц после редактирования , но я не знаю, как соединить 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 ]

2 голосов
/ 18 марта 2019

В этой ситуации DT::replaceData с resetPaging = FALSE должно работать нормально, как показано здесь .Однако определение 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)
    })
  }
0 голосов
/ 18 марта 2019

Это мое предложение:

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)

Я не уверен, что это самый чистый способ, но это лучшее, что я смог сделать.

...