Search code examples
rshinydashboard

How to swich between NavBar Tabs without bottom in R Shin


I am creating a dashboard with multiple tabs in R shiny, it is possible that after a certain time, the dashboard will automatically switch from table 1 to tab 2 without the need for a button.


Solution

  • Here a fully working example.

    1. The timer is set to 10 seconds. You can see the remaining time before switching to tab 2 (source for this part here on SO).
    2. After the time has elapsed the first observe uses updateTabsetPanel to switch the tab. The timer is "stopped" (in this case simply ignored).
    3. If a user switches tabs manually, the timer will be stopped by the second observe.

    This solution uses a shiny::tabsetPanel (more). If you prefer shinydashboard::tabItems you have to use updateTabItems instead of updateTabsetPanel.

    library(shiny)
    
    ui <- fluidPage(
      # App title ----
      titlePanel("Auto Tabsets"),
      
      # Sidebar layout with input and output definitions ----
      sidebarLayout(
        
        # Sidebar panel for inputs ----
        sidebarPanel(
        ),
        
        # Main panel for displaying outputs ----
        mainPanel(
          
          # Output: Tabset w/ plot, summary, and table ----
          tabsetPanel(id = "inTabset", type = "tabs",
                      tabPanel("Tab 1", verbatimTextOutput("timeleft")),
                      tabPanel("Tab 2", verbatimTextOutput("data"))
          )
        )
      )
    )
    
    server <- function(input, output, session) {
      # Initialize the timer, 10 seconds, active.
      timer <- reactiveVal(10) # in seconds
      active <- reactiveVal(TRUE)
      
      
      # Output the time left and timer status on tab 1
      output$timeleft <- renderText({
        paste("Time left: ", timer(), " - Timer ", ifelse(active(), "On", "Off"))
      })
      
      # Output the time left and timer status on tab 2
      output$data <- renderText({
        paste("Time left: ", timer(), " - Timer ", ifelse(active(), "On", "Off"))
      })
      
      
      
      # TIMER
      # observer that invalidates every second. If timer is active, decrease by one.
      observe({
        invalidateLater(1000, session)
        isolate({
          if(active())
          {
            timer(timer()-1)
            if(timer() < 1)
            {
              active(FALSE)
              updateTabsetPanel(session, "inTabset", selected = "Tab 2")
            }
          }
        })
      })
      
      
      # TABSET
      # Stop the timer if the user changes the tab manually
      observe({
        if (input$inTabset != "Tab 1")
          isolate(active(FALSE))
      })
    }
    
    shinyApp(ui, server)