I'd like to synchronize the scrolling of two handsontables in a shiny app. I tried some attempts based on proposals given here and here. I also tried with the jquery.scrollSync library, my code is below. Nothing works.
library(shiny)
library(rhandsontable)
ui = shinyUI(fluidPage(
tags$head(tags$script(src = "http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js")),
sidebarLayout(
sidebarPanel(),
mainPanel(
rHandsontableOutput("hot", width = 350),
rHandsontableOutput("hot2", width = 350),
singleton(
tags$script(HTML('$("#hot").addClass("scrollable");'))
),
singleton(
tags$script(HTML('$("#hot2").addClass("scrollable");'))
),
singleton(
tags$script(HTML('$(".scrollable").scrollSync();'))
)
)
)
))
server = shinyServer(function(input, output, session) {
values = reactiveValues()
data = reactive({
if (!is.null(input$hot)) {
DF = hot_to_r(input$hot)
} else {
if (is.null(values[["DF"]]))
DF = mtcars[1:3,]
else
DF = values[["DF"]]
}
values[["DF"]] = DF
DF
})
output$hot <- renderRHandsontable({
DF = data()
if (!is.null(DF))
rhandsontable(DF, stretchH = "all")
})
output$hot2 <- renderRHandsontable({
rhandsontable(mtcars[1:3,], stretchH = "all")
})
})
runApp(list(ui=ui, server=server))
Edit
Below is an unsuccessful attempt to use scrollViewportTo
.
library(shiny)
library(rhandsontable)
jscode <- "
$('#scroll').on('click', function () {
$('#hot').scrollViewportTo(1,5);
});
"
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("scroll", "Scroll")
),
mainPanel(
rHandsontableOutput("hot", width = 350),
singleton(
tags$script(HTML(jscode))
)
)
)
))
server = shinyServer(function(input, output, session) {
values = reactiveValues()
data = reactive({
if (!is.null(input$hot)) {
DF = hot_to_r(input$hot)
} else {
if (is.null(values[["DF"]]))
DF = mtcars[1:3,]
else
DF = values[["DF"]]
}
values[["DF"]] = DF
DF
})
output$hot <- renderRHandsontable({
DF = data()
if (!is.null(DF))
rhandsontable(DF, stretchH = "all")
})
})
runApp(list(ui=ui, server=server))
A solution. My case is specific: the second table has only one row, with the same number of columns as the first table, and the user only scrolls the first table.
It is also possible to have the same column widths for the two tables, but this is not done in the code below.
It would be better if the scrolling were not continuous, if it jumped row by row.Solved: see the edit at the end.EDIT:
For a better alignment, use: