Home > Software engineering >  How to apply horizontal scroll for top and bottom on multiple tables in a Shiny app?
How to apply horizontal scroll for top and bottom on multiple tables in a Shiny app?

Time:06-21

I want multiple tables to have top and bottom horizontal scroll. I found a solution using jQuery inside the app, however, it only works for the first table. When I specify (as shown and using the function for each one separately) it does not work for table2 or table3, only table1.

I'm not familar with jQuery so I don't know if there's an issue with the jQuery script or there is something else. I also noticed the tables don't respect the specified structure and assume there's a link between these two problems. Any suggestions?

library(formattable)
library(shiny)

js <- "
$(document).ready(function(){
  $('#table1, #table2, #table3').on('shiny:value', function(e){
    setTimeout(function(){
      $('#table1 table, #table2 table, #table3 table').wrap('<div id=\"scrolldiv\"></div>');
      $('#scrolldiv').doubleScroll({
        contentElement: $('table'),
          scrollCss: {                
              'overflow-x': 'scroll',
              'overflow-y': 'hidden'
          },
          contentCss: {
              'overflow-x': 'scroll',
              'overflow-y': 'hidden'
          },
        resetOnWindowResize: true
      });
      setTimeout(function(){$(window).resize();}, 100);
    }, 0);
  });
});

"

CSS <- "
.doubleScroll-scroll-wrapper {
  clear: both;
}
"

ui <- fluidPage(
  
  tags$head(
    tags$script(src = "jquery.doubleScroll.js"),
    tags$script(HTML(js)),
    tags$style(HTML(CSS))
  ),
  
  fluidRow(column(2,formattableOutput("table1"))),
  fluidRow(column(2,formattableOutput("table2"))),
  fluidRow(column(2,formattableOutput("table3")))
  
)

server <- function(input, output) {
  
  output$table1 <- renderFormattable({
    formattable(mtcars)
  })
  
  output$table2 <- renderFormattable({
    formattable(mtcars)
  })
  
  output$table3 <- renderFormattable({
    formattable(mtcars) 
  })
  
  
}

shinyApp(ui = ui, server = server)

CodePudding user response:

That works only for the first table because you use the same id scrolldiv. Duplicated ids are not allowed in HTML. Use this JS code:

js <- "
$(document).ready(function(){
  $('#table1, #table2, #table3').on('shiny:value', function(e){
    var id = this.id;
    var scrolldiv = 'scrolldiv'   id;
    var div = '<div id=\"'   scrolldiv   '\"></div>';
    var $this = $(this);
    setTimeout(function(){
      $this.find('table').wrap(div);
      $('#' scrolldiv).doubleScroll({
        contentElement: $('table'),
          scrollCss: {                
              'overflow-x': 'scroll',
              'overflow-y': 'hidden'
          },
          contentCss: {
              'overflow-x': 'scroll',
              'overflow-y': 'hidden'
          },
        resetOnWindowResize: true
      });
      setTimeout(function(){$(window).resize();}, 100);
    }, 0);
  });
});
"

In the GIF below, I use:

  fluidRow(
    column(4, formattableOutput("table1")),
    column(4, formattableOutput("table2")),
    column(4, formattableOutput("table3"))
  )

enter image description here

  • Related