Search code examples
rshinydt

How to get DT::datatable to update when hidden


When datatables are hidden in Shiny, they seem to not update, even if outputOptions(output, 'tableID', suspendWhenHidden=FALSE) is used. Below is an MRE. If you hide the datatable, and then add or delete rows, and then show the datatable, you'll see that it's not updated. However, as soon as you modify the datatable while it's visible, all past changes "catch up" with it. How can we force datatables to redraw themselves while they're hidden?

#ui
shinyUI(
  #tags$head(tags$script(src="main.js")),
  fluidPage(    
    titlePanel("Modifying Hidden Datatable"),
    sidebarLayout(      
      sidebarPanel(
        actionButton("decrease", "Decrease Row Number"),
        actionButton("increase", "Increase Row Number"),
        actionButton("hide", "Hide Data Table"),
        actionButton("show", "Show Data Table")
      ),
      mainPanel(
        tags$head(tags$script(src="main.js")),
        DT::dataTableOutput("df")  
      )
    )
  )
)

#server
library(shiny)
library(DT)

shinyServer(function(input, output, session) {

  values = reactiveValues(n = 1)

  observeEvent(input$decrease, {
    values$n = values$n - 1
    if (values$n == 0) values$n = 1
  })

  observeEvent(input$increase, {
    values$n = values$n + 1
    if (values$n > nrow(mtcars)) values$n = nrow(mtcars)
  })

  output$df = renderDataTable({
    df = mtcars[1:values$n, ]
    DT::datatable(df)
  })
  outputOptions(output, "df", suspendWhenHidden=FALSE)
})

#javascript
$(document).ready(function() {
  $('#hide').click(function() {
    $('#df').hide();
  });
  $('#show').click(function() {
    $('#df').show();
  });
});

Solution

  • It turns out that if you're already using Javascript, you can just call the draw function on the table. The following Javascript code should work:

    $(document).ready(function() {
      $('#hide').click(function() {
        $('#df').hide();
      });
      $('#show').click(function() {
        $('#df').show();
        $("#df table").DataTable().draw();
      });
    });