0

I use DT::renderDataTable to render a data table for a Shiny app and I use editable = TRUE in the definition of datatable(). The data argument of datatable is a reactive expression that gets data from a database based on the selected value from a dropdown menu. I want to be able to have a button that refreshes the datatable and discards any user edits, just like selecting another value from the dropdown menu. I can't give you a reproducible example because I am using proprietary code and data that come from a database. I know I can use an observeEvent on the refresh button click event and then call the render function of the table, but I am looking for a more elegant approach. Thanks

Stelios M
  • 160
  • 1
  • 1
  • 11
  • Will something like this solve your problem: [add a page refresh button by using rshiny](https://stackoverflow.com/questions/30852356/add-a-page-refresh-button-by-using-r-shiny) – DS_UNI Mar 13 '19 at 08:36
  • You can add a choice `Discard all` that render the original data and test for it inside your `DT::renderDataTable` – Clemsang Mar 13 '19 at 08:37
  • @Clemsang can you elaborate on that? I am not sure I follow you. – Stelios M Mar 13 '19 at 12:35
  • You add a choice to the drop down. If the drop down is `Discard all`, you render the initial data, else you modifiy as usual the current data and render it – Clemsang Mar 13 '19 at 12:49

2 Answers2

0

Found out that you can use proxy <- datatableProxy() and then reloadData(proxy) inside the observeEvent of the refresh button. This would cancel any datatable edits made.

Stelios M
  • 160
  • 1
  • 1
  • 11
0

Thanks @Stelios!

Here's a reprex adapted from https://github.com/rstudio/DT/issues/357#issuecomment-247423310

library(shiny)
shinyApp(
  ui = fluidPage(
    fluidRow(
      column(2, actionButton('refresh', 'Refresh Data', icon = icon('refresh'))),
      column(10, DT::dataTableOutput('foo'))
    )
  ),
  server = function(input, output, session) {

    output$foo = DT::renderDataTable(
      iris, 
      selection = 'none', 
      editable = 'all',
      caption = 'Double-click to edit cells. Press Ctrl+Enter to save changes.'
    )
    
    proxy = dataTableProxy('foo')
    
    observeEvent(input$refresh, {
      DT::reloadData(proxy)
    })
  }
)

And, in the spirit of the aforementioned post, it works with modules.

library(shiny)

edit_dt_ui <- function(id) {
  tagList(
    fluidRow(
      column(2, actionButton(NS(id, 'refresh'), 'Refresh Data', icon = icon('refresh'))),
      column(10, DT::dataTableOutput(NS(id, 'foo')))
    )
  )
}

edit_dt_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    output$foo <- DT::renderDataTable(
      iris, 
      selection = 'none', 
      editable = 'all',
      caption = 'Double-click to edit cells. Press Ctrl+Enter to save changes.'
    )
    
    proxy <- dataTableProxy('foo')
    
    observeEvent(input$refresh, {
      DT::reloadData(proxy)
    })
    
  })
}

ui <- fluidPage(
  edit_dt_ui('dt')
)

server <- function(input, output, session) {
  edit_dt_server('dt')
}

shinyApp(ui, server)
bm5tev3
  • 21
  • 5