Search code examples
rshinycallbackdt

Shiny datatable rowGroup actionButton collapse/expand


I have designed a basic Shiny App including a datatable with a rowGroup argument.

Now, I'd like to add an actionButton() that would collapse/expand all lines of the datatable on button press.

Currently, the code collapses by default all rows based on the rowGroupargument and each rowGroup can be opened one-by-one on mouse click (which is nice), but I'd also like to add a button that expand/collapse all rows simultaneously.

Here is a reproducible example (inspired from this thread):

library(shiny)
library(DT)
ui <- fluidPage(# Application title
  titlePanel("Collapse/Expand table"),
  mainPanel(
    tabsetPanel(
      tabPanel("table1", actionButton("expandButton", "Expand/Collapse"),dataTableOutput("my_table")) 
    )
  ))

server <- function(input, output) {
  output$my_table <- DT::renderDataTable({
    datatable(
      mtcars[1:15, 1:5],
      extensions = c('RowGroup',"Buttons"),
      options = list(rowGroup = list(dataSrc = 3), 
                 pageLength = 20, 
                 dom = 'tB',
                 buttons = list(list(extend = "",
                                text = "Collapse rowGroup",
                                action = JS("function (e, dt, node, config) {dt.rowGroup().dataSrc('').draw();}")))), 
      callback = JS(
        "table.on('click', 'tr.dtrg-group', function () {",
        "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
        "  $(rowsCollapse).toggleClass('hidden');",
        "});",
        "table.one('init', () => $('#my_table .dtrg-group').trigger('click'))"
      ),
      selection = 'none'
    )
  })
}

# Run the application
shinyApp(ui = ui, server = server)

Would you have any suggestions (my understanding of javascript is extremely limited)?

Thanks,

C.


Solution

  • In DT, except very recent, only the number of the column works.

    On the callback you can bind the expand button.

    Good job to have found options / buttons / action R Shiny DT equivalent of pure javascript implementation :)

    library(shiny)
    library(DT)
    ui <- fluidPage(# Application title
      titlePanel("Collapse/Expand table"),
      mainPanel(
        tabsetPanel(
          tabPanel("table1", 
                   actionButton("expandButton", "Expand/Collapse"),
                   dataTableOutput("my_table")
          ) 
        )
      ))
    
    server <- function(input, output) {
      output$my_table <- DT::renderDataTable({
        datatable(
          mtcars[1:15, 1:5],
          extensions = c('RowGroup',"Buttons"),
          options = list(rowGroup = 
                           list(
                             dataSrc = 3 # disp
                           ), 
                         pageLength = 20, 
                         dom = 'tB',
                         buttons = list(
                           list(extend = "",
                                text = "UnGroup rowGroup disp",
                                action = JS("function (e, dt, node, config) {dt.rowGroup().dataSrc('').draw();}")
                           ),
                           list(extend = "",
                                text = "Group rowGroup disp",
                                action = JS("function (e, dt, node, config) {dt.rowGroup().dataSrc(3).draw();}")
                           )                       
                         )
          ), 
          callback = JS(
            "table.on('click', 'tr.dtrg-group', function () {",
            "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
            "  $(rowsCollapse).toggleClass('hidden');",
            "});",
            "table.one('init', () => $('#my_table .dtrg-group').trigger('click'))",
            "$('#expandButton').on('click', function(){",
            "  $('#my_table').toggleClass('hidden')",
            "});"
          ),
          selection = 'none'
        )
      })
    }
    
    # Run the application
    shinyApp(ui = ui, server = server)