2

I am building a datatable in R Shiny to display data with many columns and rows. I had two problems at first:

  1. When the user was scrolling down the table, the header of the table disappeared. This has been fixed thanks to this SO post.
  2. When a user wishes to go left or right of the table, he has to scroll to the bottom of the page (or top depending on where you display the scrollbar). This is an inconvenience to repeat this task especially when displaying many rows. So, my aim is to add a horizontal scrollbar to the fixed header. Would this be possible?

I searched the internet and I found this post that may contain the answer but not sure how to implement it in my case.

The following reproducible code will spawn a table with 50 rows and 30 columns:

library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(dplyr)
library(data.table)
library(tidyverse)
library(DT)

myFun <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}

dt <- setDT(data.frame(replicate(30,sample(myFun(50),50,rep=TRUE))))

ui <- fluidPage(theme = "slate",
  navbarPage(title = "Test",

  header = tagList(
    useShinydashboard(),
  ),
  tabPanel(
    "Table",
    fluidRow(
      box(dataTableOutput("mytable"),
        width = 12,
        collapsible = FALSE,
        title = "",
        solidHeader = T
      )
    )
  )
)
  )

# server
server <- function(input, output) {
 

  output$mytable <-
    renderDataTable(
      dt,
      filter = list(position = "top", clear = FALSE, plain = TRUE),
      extensions = c("FixedHeader"),
      options = list(
        scrollX = T,
        fixedHeader=T,
        pageLength = 50,
        autoWidth = F,
        search = list(regex = TRUE),
        # the following is used to cut the string if its too long
        columnDefs = list(
          list(
            targets = "_all",
            render = JS(
              "function(data, type, row, meta) {",
              "return type === 'display' && data != null && data.length > 5 ?",
              "'<span title=\"' + data + '\">' + data.substr(0, 5) + '...</span>' : data;",
              "}"
            )
          )
        )
      ),
      rownames = FALSE
    )


}
# app
shinyApp(ui, server)

Will generate a Shiny app:

enter image description here

Any help is kindly appreciated. Thanks in advance.

user324810
  • 597
  • 8
  • 20

1 Answers1

0

The vertical scrollbar that appears is actually for the whole page, not the datatable. You need to restrict the height of your datatable, so it doesn't overflow the page, and add the vertical bar. You can do that by adding

scrollY = 300

to your table options, where "300" is the height of your datatable. Depending on your userbase, what devices they are using etc. you will need to adjust this number or find an appropriate way of setting it automatically.

The above would also fix the problem with disappearing header, since you are actually scrolling table body instead of the whole page.

Radvvan
  • 145
  • 5
  • Thank you for the proposed answer but this does not fully answer my question because, as you said, this needs to be adjusted to the user's browser. Unless you provide a way to automatically set this number, I am not sure how to do it. – user324810 Nov 10 '22 at 13:41
  • @user324810 Literaly 30 seconds of searching: [LINK](https://stackoverflow.com/questions/36995142/get-the-size-of-the-window-in-shiny). You can use the code in tags$head(tags$script()), and use input$dimensions[[1]] for your scrollY value. Might need some tweaking based on other elements of the app, but this will be app-specific, not user/browser-specific. – Radvvan Nov 10 '22 at 14:32