Make an active reset sort or replace datatable button in datatable in shiny

Viewed 174

I am trying to place a button inside the datatable where if the user wants to reset the sorted column they can hit the button and table gets reset or changed to it's original order. At the moment, when I press the button, it is not triggering any event on click. The event should replace the data in the server part.

I am currently following these posts:

  1. shiny DT datatable - reset filters
  2. https://github.com/rstudio/DT/issues/76
  3. Reset a DT table to the original sort order

However, in the last two posts above, even though they get the job done, the button is not part of the datatable.

Here is my reprex:

library(DT)
library(shiny)
library(shinyjs)

# function placed in the global.R
clearSorting <- function(proxy) {
  shinyjs::runjs(paste0("$('#' + document.getElementById('", proxy$id,"').getElementsByTagName('table')[0].id).dataTable().fnSort([]);"))
}

# ui.R
ui <- fluidPage(
  DT::DTOutput(outputId = "table"),
  shinyjs::useShinyjs()
)

# servcer.R
server <- function(input, output) {
  
  output$table <- renderDT({
    
    DT::datatable(data = iris,
                  filter = 'top',
                  extensions = c('Buttons'),
                  
                  options = list(scrollY = 600,
                                 scrollX = TRUE,
                                 autoWidth = TRUE,
                                 dom =  '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
                                 buttons = list(
                                   list(
                                     extend = '',
                                     text = 'Reset Table',
                                     action = JS("function() {document.getElementById('reset_sort').click();}")
                                   )
                                 ),
                                 scrollCollapse= TRUE,
                                 lengthChange = TRUE,
                                 widthChange= TRUE))
  })
  
  observeEvent(input$reset_sort, {
    
    data <- iris
    
    clearSorting(proxy = DT::dataTableProxy(outputId = "table"))
    
    DT::replaceData(proxy = DT::dataTableProxy(outputId = "table"),
                data = data,
                rownames = FALSE)
    
  })
  
}

shinyApp(ui = ui, server = server)
1 Answers

Here is a way:

library(DT)

js <- c(
  "function(e, dt, node, config){",
  "  dt.iterator('table', function(s){",
  "    s.aaSorting.length = 0;",
  "    s.aiDisplay.sort(function(a,b){",
  "       return a-b;",
  "    });",
  "    s.aiDisplayMaster.sort(function(a,b){",
  "       return a-b;",
  "    });",
  "  }).draw();",
  "}"
)

datatable(
  iris,
  extensions = "Buttons",
  options = list(
    dom = "Bfrtip",
    buttons = list(
      list(
        extend = "collection", 
        text = "Reset columns order", 
        action = JS(js)
      )
    )
  )
)

To use it in Shiny, you may need to set server = FALSE in renderDT:

output$table <- renderDT({
  ......
}, server = FALSE) 
Related