I have a tabbed shiny app that generates quite a bit of content based on user inputs and I'm trying to figure out how to scroll to the bottom of the active tab each time new content is generated. I tried implementing the answer given in this question but it doesn't seem to work. I'm have minimal experience with javaScript so it may just be something needs to be changed for my specific example. Here is a very silly toy example with my attempt at implementing the answer from the linked question:
library(shiny)
ui <- fluidPage(
tags$script(
'
Shiny.addCustomMessageHandler("scrollCallback",
function(color) {
var objDiv = document.getElementById("outDiv");
objDiv.scrollTop = objDiv.scrollHeight;
}
);'
),
tabsetPanel(id = "mainPanels",
tabPanel("FirstPanel",
actionButton("outGen", "GenerateOutput"))),
uiOutput("randomOutput")
)
server <- function(input, output, session) {
output$randomOutput <- renderUI({
req(input$outGen)
lapply(1:50, function(x)p("FooBar"))
})
observeEvent(input$outGen,{
session$sendCustomMessage(type = "scrollCallback", 1)
})
}
runApp(shinyApp(ui,server))
I'm trying to find a way to scroll to the bottom of the tab once the generate output button is pressed.
Here is a fixup that works. The following changes were made:
div before we start. This is necessary otherwise some of the variables will not be initialized properly in the div object.randomOutput div so that you would have a scroll bar to scroll.getElementById was querying the wrong div)scrollCallbackHere is the code:
library(shiny)
ui <- fluidPage(
tags$style('#randomOutput { height: 450px; overflow: auto;}'),
tags$script(
'
Shiny.addCustomMessageHandler("scrollCallback",
function(msg) {
console.log("aCMH" + msg)
var objDiv = document.getElementById("randomOutput");
objDiv.scrollTop = objDiv.scrollHeight - objDiv.clientHeight;
console.dir(objDiv)
console.log("sT:"+objDiv.scrollTop+" = sH:"+objDiv.scrollHeight+" cH:"+objDiv.clientHeight)
}
);'
),
tabsetPanel(id = "mainPanels",
tabPanel("FirstPanel",
actionButton("outGen", "GenerateOutput"))),
uiOutput("randomOutput")
)
server <- function(input, output, session) {
n <- 0
output$randomOutput <- renderUI({
input$outGen
n <<- n + 50
lapply(1:50, function(x)p(paste0("FooBar-",x+n-50)))
})
observeEvent(input$outGen,{
session$sendCustomMessage(type = "scrollCallback", 1)
})
}
runApp(shinyApp(ui,server))
and here is what it looks like on testing:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With