Workaround for issues with freezing header in DT::datatable() in R Shiny

Viewed 142

I am using DT::datatable() in an R Shiny app to render a table with the header and first column fixed. My app has multiple tabs. I've tried two different approaches but both have bugs that make them unusable. I'm aware that these issues have been reported but I was wondering if anyone knows a workaround that would work in my case.

Approach # 1: scrollY

Here I set scrollY = "500px" in options. The problem is that when I change the number of entries to something other than 10, when I scroll to the bottom, the first column is misaligned with the other columns.

require(shiny)
require(DT)

shinyApp(
  ui = tabsetPanel(
    tabPanel(
      title = "Tab 1",
      fluidPage(
        DTOutput("table1")
      )
    ),
    tabPanel(
      title = "Tab 2",
      fluidPage(
        plotOutput("myPlot"),
        DTOutput("table2")
      )
    )
  ),
  server = function(input, output, session) {
    
    output$table1 <- DT::renderDataTable({
      
      myData <- cbind(iris, iris, iris, iris)
      colnames(myData) <- paste0("Column ", 1:ncol(myData))
      
      DT::datatable(
        data = myData, 
        extensions = "FixedColumns", 
        rownames = F,
        options = list(
          scrollX = T, 
          scrollY = "500px",
          fixedColumns = list(leftColumns = 1)
        ) 
      ) 
    })
    
    output$myPlot <- renderPlot({
      plot(1:10, 1:10)
    })
    
    output$table2 <- DT::renderDataTable({
      DT::datatable(iris)
    })
    
  }
)

enter image description here

Approach # 2: FixedHeader extension

Here I use the FixedHeader extension and set fixedHeader = T in options. This avoids the issue with approach # 1, but it has a more serious issue. The fixed header from the table appears on other tabs. In this example, if I scroll down the table on Tab 1, the headers remain fixed as expected, but when I switch to Tab 2 and scroll down, the fixed headers from the table on Tab 1 appear on Tab 2.

require(shiny)
require(DT)

shinyApp(
  ui = tabsetPanel(
    tabPanel(
      title = "Tab 1",
      fluidPage(
        DTOutput("table1")
      )
    ),
    tabPanel(
      title = "Tab 2",
      fluidPage(
        plotOutput("myPlot"),
        DTOutput("table2")
      )
    )
  ),
  server = function(input, output, session) {
    
    output$table1 <- DT::renderDataTable({
      
      myData <- cbind(iris, iris, iris, iris)
      colnames(myData) <- paste0("Column ", 1:ncol(myData))
      
      DT::datatable(
        data = myData, 
        extensions = c("FixedColumns", "FixedHeader"), 
        rownames = F,
        options = list(
          scrollX = T, 
          fixedHeader = T,
          fixedColumns = list(leftColumns = 1)
        ) 
      ) 
    })
    
    output$myPlot <- renderPlot({
      plot(1:10, 1:10)
    })
    
    output$table2 <- DT::renderDataTable({
      DT::datatable(iris)
    })
    
  }
)

enter image description here

1 Answers

Updating DT from version 0.19 to version 0.20 (released 11/15/2021) fixed the issue so approach #1 works correctly.

Related