1

I'm putting together a shinyApp to work as an survey board for number of psychological questionnaires.

Every tab is another study, and inside an app there is a number of conditional panels (as next pages of the survey). To navigate throught pages, there is another panel at the end of page. After changing pages I would like the browser to navigate to the top of new page (the beginning of next questionnaire).

I've tried to base a solution on How to add a "back to top of page" button in R Shiny?, but with observeEvent being the change to the slider. Unfortunately, it won't work. As a matter of fact, it seem to not do anything.

I've created an example of the problem in the code below:

library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)

##### Shinyjs Code

jscode <- "shinyjs.toTop = function() {document.body.scrollTop = 0;}"

UI <- dashboardPage(skin = "black",

                # Title of app
                dashboardHeader(title = "Minimal working example", titleWidth = 600),
                
                # Tabs setup
                dashboardSidebar(sidebarMenu(menuItem("Info",
                                                      tabName = "info",
                                                      icon = icon("info")),
                                             menuItem("Survey",
                                                      tabName = "survey",
                                                      icon = icon("chart-bar"))
                                             
                )
                ),
                
                # Main body with two tabs
                dashboardBody(
                  
                  tabItems(
                  
                  # Info about
                  
                  tabItem(tabName = "info", tags$title("Info"),
                          fluidPage(
                            box(title = "Hi!", width = 40,
                                "This is the first tab of example"))),
                  
                  # Survey
                  
                  tabItem(tabName = "survey", tags$title("Survey"),
                          
                          #Page first, Shinyjs implementation
                          
                          fluidPage(useShinyjs(),
                                    extendShinyjs(text = jscode,
                                                  functions = "toTop"),
                                    
                            conditionalPanel("input.slider_page == 'page1'",
                                             tags$h1("First page of survey"),
                                             "Now a lot of text", 
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "More text",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "Some more items",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "Some more items",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "And now the slider to choose the page"),
                            
                            # Second page
                            
                            conditionalPanel("input.slider_page == 'page2'",
                                             tags$h2("Second page of the survey"),
                                             "This should be visible after turning the page", 
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "More text",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "Some more items",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "Some more items",
                                             hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                             "And this should not be visible just after turning pages"),
                            
                            #Slider to change a page
                            
                            fluidRow(sliderTextInput("slider_page",
                                                     label = "Choose a page",
                                                     choices = c("page1",
                                                                 "page2"),
                                                     selected = c("page1")))
                          )
                          
                          ))))

server <- function(input, output) {
  
  # observeEvent to execute javascript to go to the top of the page
  
  observeEvent(input$slider_page,{
    
    js$toTop();
    
               })
  
}

shinyApp(UI, server)
M_Kos
  • 78
  • 8

1 Answers1

0

Ok, so I've finally got it. I've found the accepted answer from R Shiny Dashboard Scroll to Top on Button Click to work in my code.

If you need to utilize the same functionality for multiple tabs, which have multiple pages and sliders, you may study the answers to this question: How to listen for more than one event expression within a Shiny observeEvent

Below I paste my modified minimal reproductive example - it may help anyone with similar trouble to mine.


##### Shinyjs Code

UI <- dashboardPage(skin = "black",
                    
                    # Title of app
                    dashboardHeader(title = "Minimal working example", titleWidth = 600),
                    
                    # Tabs setup
                    dashboardSidebar(sidebarMenu(menuItem("Info",
                                                          tabName = "info",
                                                          icon = icon("info")),
                                                 menuItem("Survey",
                                                          tabName = "survey",
                                                          icon = icon("chart-bar"))
                                                 
                    )
                    ),
                    
                    # Main body with two tabs
                    dashboardBody(
                      
                      tabItems(
                        
                        # Info about
                        
                        tabItem(tabName = "info", tags$title("Info"),
                                useShinyjs(), # Only this call is needed in UI to initialize ShinyJS
                                fluidPage(
                                  box(title = "Hi!", width = 40,
                                      "This is the first tab of example"))),
                        
                        # Survey
                        
                        tabItem(tabName = "survey", tags$title("Survey"),
                                
                                fluidPage(
                                          
                                          conditionalPanel("input.slider_page == 'page1'",
                                                           tags$h1("First page of survey"),
                                                           "Now a lot of text", 
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "More text",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "Some more items",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "Some more items",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "And now the slider to choose the page"),
                                          
                                          # Second page
                                          
                                          conditionalPanel("input.slider_page == 'page2'",
                                                           tags$h2("Second page of the survey"),
                                                           "This should be visible after turning the page", 
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "More text",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "Some more items",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "Some more items",
                                                           hr(),hr(),hr(),hr(),hr(), hr(),hr(),
                                                           "And this should not be visible just after turning pages"),
                                          
                                          #Slider to change a page
                                          
                                          fluidRow(sliderTextInput("slider_page",
                                                                   label = "Choose a page",
                                                                   choices = c("page1",
                                                                               "page2"),
                                                                   selected = c("page1")))
                                )
                                
                        ))))

server <- function(input, output) {
  
  # observeEvent to execute javascript to go to the top of the page
  
  observe({
    
    # You can add multiple triggers here if there are multiple (n) tabs with changing pages in your app
    
    input$slider_page
 #  input$slider_2_page
 #  ....
 #  input$slider_n_page
    
    # And this JS code works finally :)
    
    shinyjs::runjs("window.scrollTo(0, 0)")
    
  })
  
}

shinyApp(UI, server)
M_Kos
  • 78
  • 8