Sticky Column and Row Names in Rhandsontable

182 Views Asked by At

I am currently developing a Shiny application and utilizing the rhandsontable package to display a table. Here is the code snippet I am working with:

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  mainPanel(
    rHandsontableOutput("myTable")
  )
)

server <- function(input, output) {
  output$myTable <- renderRHandsontable({
    df <- data.frame(matrix(1:(50**2), ncol = 50))
    rhandsontable(df, height = 10000, width = 10000)
  })
}

shinyApp(ui = ui, server = server)

My goal is to implement sticky column and row names in the rhandsontable output. However, I want to achieve this without constraining the height or width of the table. I've currently set a large height and width to avoid multiple scrollbars (from the constrained table and the large webpage), as it can be confusing for users when these scrollbars are in close proximity. Note also that in my project, the data from the table is dynamically generated, so I don't know in advance what is the exact height and width of the table.

I've attempted several methods to achieve this, but none have been successful.


Edit
I would like my rhandsontable to exhibit the same behavior in terms of sticky row names and row headers (without limiting the height or width of the table) as this handsontable in JavaScript:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" />
</head>
<body>
    <div id="example1" class="hot"></div>

    <script>
        var data = [];
        for (var i = 0; i < 60; i++) {
            data[i] = [];
            for (var j = 0; j < 60; j++) {
                data[i][j] = null;
            }
        }

        var container = document.getElementById('example1');
        var hot = new Handsontable(container, {
            data: data,
            rowHeaders: true,
            colHeaders: true,
            filters: false,
            dropdownMenu: false
        });
    </script>
</body>
</html>
3

There are 3 best solutions below

1
Umar On

This example uses the hot_table function within the rhandsontable call to make row names sticky (stickyRows = TRUE) and include column headers (colHeaders = TRUE)

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  mainPanel(
    rHandsontableOutput("myTable")
  )
)

server <- function(input, output) {
  output$myTable <- renderRHandsontable({
    df <- data.frame(matrix(1:(50**2), ncol = 50))
    
    rhandsontable(df, height = 500, width = 800) %>%
    #rhandsontable(df) %>% #or use this
      hot_table(stickyRows = TRUE, 
                colHeaders = TRUE)
  })
}

shinyApp(ui = ui, server = server)
1
CPB On

An approach based on hiding the scrollbars with CSS. You can change the width and height.

library(shiny)
library(rhandsontable)

# Add CSS to hide scrollbars - may not work on all browsers.
ui <- fluidPage(
  tags$head(
    tags$style(HTML(
      "::-webkit-scrollbar {
         display: none;
        }"
    ))
  ),
  mainPanel(
    rHandsontableOutput("myTable")
  )
)

# Set the width and height to reasonable values to get the hidden scroll bars working.
server <- function(input, output) {
  output$myTable <- renderRHandsontable({
    df <- data.frame(matrix(1:(50**2), ncol = 50))
    rhandsontable(df, width = "100%", height = 500,
                  fixedRowsTop = 0, fixedColsLeft = 0)
  })
}

shinyApp(ui = ui, server = server)
5
Mohamed Imran On

you might use JavaScript directly

     library(shiny)
library(rhandsontable)

ui <- fluidPage(
  mainPanel(
    rHandsontableOutput("myTable")
  ),
  tags$head(
    tags$style(HTML("
      .rhandsontable .ht_master {
        overflow-x: hidden !important;
      }
    "))
  )
)

server <- function(input, output) {
  output$myTable <- renderRHandsontable({
    df <- data.frame(matrix(1:(50**2), ncol = 50))
    rhandsontable(df, options = list(
      stickyHeaders = TRUE
    ))
  })
}

shinyApp(ui = ui, server = server)

This sets the overflow-x property to hidden for the main container to avoid the horizontal scrollbar. Additionally, the stickyHeaders option in rhandsontable ensures sticky row and column headers without additional JavaScript or CSS.