Update row(s) of a Shiny DataTable while maintaining position

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 23:07:33

问题


I am creating a Shiny app that displays data.frame information at the top of the screen and specific variable stats at the bottom. The user can navigate the data.frame columns by interacting with a DT::datatable object.

When a user clicks on a variable, detailed information is presented that can be edited. I would like this information to be updated and reflected in the datatable. My problem is that when I update the table, it is rendered and shown starting at the very beginning. How can I preserve the page and row selection of the datatable after making edits?

Here is a minimal working example that shows the mtcars dataset in a DT::datatable. I have some controls that update fields. Notice that datatable is re-rendered back to the first page.

library(shiny)

runApp(shinyApp(

  ui = fluidPage(
    title = "minimal-working-example",
    fluidRow(
      column(3, inputPanel(
        selectInput("field", "Field", choices = names(mtcars)),
        numericInput("value", "Value", 0),
        actionButton("submit", "Submit")
      )),

      column(9,
        DT::dataTableOutput("table")
      )
    )
  ),

  server = function(input, output) {

    v <- reactiveValues(mtcars=mtcars)

    observeEvent(input$submit, {
      v$mtcars[input$field] <- input$value
    })

    output$table <- DT::renderDataTable({
      DT::datatable(
        v$mtcars,
        selection = "single",
        options = list(pageLength = 5))
    })
  }
))

Session Info:

Session info --------------------------
 setting  value                       
 version  R version 3.3.0 (2016-05-03)
 system   x86_64, mingw32             
 ui       RStudio (0.99.902)          
 language (EN)                        
 collate  English_United States.1252  
 tz       America/Chicago             
 date     2016-07-11                  

Packages -------------------------------
 package     * version     date       source                        
 DT            0.1.45      2016-02-09 Github (rstudio/DT@a63e9ac)   
 shiny       * 0.13.0.9000 2016-02-08 Github (rstudio/shiny@e871934)

回答1:


This can be done from inside R without getting into the structure of the datatable through JS or something like that.

We utilize the various table state information we get from the DT package to render the new updated datatable like the one before. Everything we use is discribed in this DT documentation.

Item one: Selection. You can pre-select rows by adding selected = ... inside the selection argument of the datatable. This can be combined with the variable input$table_rows_selected to save the previously selected row and pre-select that exact row on re-rendering.

Item two: Page. The datatable package has an option displayStart that specifies which row should be shown first when rendering the table. Documentation here. So, if you have 5 rows per page, displayStart = 9 would start the display on page 3. (JavaScript arrays start at 0, so always subtract 1.) This can be combined with input$table_rows_current which is a vector of currently visible row numbers. If we store the first entry (minus 1), we know where to start the display.

Full code example below:

library(shiny)

runApp(shinyApp(

  ui = fluidPage(
    title = "minimal-working-example",
    fluidRow(
      column(3, inputPanel(
        selectInput("field", "Field", choices = names(mtcars)),
        numericInput("value", "Value", 0),
        actionButton("submit", "Submit")
      )),

      column(9,
        DT::dataTableOutput("table")
      )
    )
  ),

  server = function(input, output) {

    v <- reactiveValues(mtcars=mtcars)
    previousSelection <- NULL
    previousPage <- NULL

    observeEvent(input$submit, {
      previousSelection <<- input$table_rows_selected
      previousPage <<- input$table_rows_current[1] - 1

      v$mtcars[input$field] <- input$value
    })

    output$table <- DT::renderDataTable({
      DT::datatable(
        v$mtcars,
        selection = list(mode = "single", target = "row", selected = previousSelection),
        options = list(pageLength = 5, displayStart = previousPage))
    })
  }
))


来源:https://stackoverflow.com/questions/38316013/update-rows-of-a-shiny-datatable-while-maintaining-position

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!