jonekeat
jonekeat

Reputation: 125

DT collapse all row groups by default

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)

Upvotes: 3

Views: 3648

Answers (2)

jonekeat
jonekeat

Reputation: 125

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)

Upvotes: 0

thothal
thothal

Reputation: 20379

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.

Upvotes: 2

Related Questions