DT collapse all row groups by default

Viewed 1197

I am trying to make all row groups in a datatable collapse by default,

my current implementation:

library(shiny)
library(DT)
ui <- fluidPage(# Application title
  titlePanel("Collapse/Expand table"),
  mainPanel(DTOutput("my_table")))

callback_js <- JS(
  "table.on('click', 'tr.dtrg-group', function () {",
  "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
  "  $(rowsCollapse).toggleClass('hidden');",
  "});"
)

server <- function(input, output) {
  output$my_table <- DT::renderDT({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      callback = callback_js,
      selection = 'none'
    )
  })
}

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

Results:

enter image description here

My desired output:

All row groups should be collapsed at initial (at 1st time table is rendered), I cannot found any solutions existed yet

Update (24 Mar 2021):

Thanks to @thothal, now the table is collapse at init, but in case of multiple DT at different tabs, the first table will expand unintended, when navigate back and forth

Code to reproduce:

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

callback_js <- JS(
  "table.on('click', 'tr.dtrg-group', function () {",
  "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
  "  $(rowsCollapse).toggleClass('hidden');",
  "});",
  "table.on('init', () => $('.dtrg-group').trigger('click'))"
)

server <- function(input, output) {
  output$my_table <- DT::renderDataTable({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      callback = callback_js,
      selection = 'none'
    )
  })
  
  output$my_table2 <- DT::renderDataTable({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      callback = callback_js,
      selection = 'none'
    )
  })
}

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

Adapt your callback as follows:

callback_js <- JS(
   "table.on('click', 'tr.dtrg-group', function () {",
   "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
   "  $(rowsCollapse).toggleClass('hidden');",
   "});",
   "table.on('init', () => $('.dtrg-group').trigger('click'))"
)

This will trigger all click events once the table is set up.

I figure out the solution for multiple DTs, we need to specify which tables to trigger 'click' event. Since DT are lazy render, when other DT render, it remove hidden class for previous table

Code:

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

server <- function(input, output) {
  output$my_table <- DT::renderDataTable({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      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'
    )
  })
  
  output$my_table2 <- DT::renderDataTable({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      callback = JS(
        "table.on('click', 'tr.dtrg-group', function () {",
        "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
        "  $(rowsCollapse).toggleClass('hidden');",
        "});",
        "table.one('init', () => $('#my_table2 .dtrg-group').trigger('click'))"
      ),
      selection = 'none'
    )
  })
}

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