Search code examples
rshinyactionlink

Use updateNavbarPage to add 'Previous' button for > 2 pages (also applies to updateTabsetPanel)


I am trying to implement a 'Previous' button on my RShiny app that navigates to a previous page when pressed. I am finding that I can get it to work for two pages, but it no longer works when I have a third page and try to navigate back to the second page. Strangely, using the same logic for a 'Next' button works just fine.

Here is a minimal reproducible example:

ui <- fluidPage(
                navbarPage(title = "",
                           id = "panels_main",
                           tabPanel(title = "A", #value = "intro_page",
                                    p(paste("Panel A")),
                                    fluidRow(column(width = 1, offset = 9, actionLink("link_to_tabpanel_B", "Next")))

                           ),

                           tabPanel(title = "B", #value = "intro_page",
                                    p(paste("Panel B")),
                                    fluidRow(
                                      column(width = 1, offset = 0, actionLink("link_to_tabpanel_A", "Previous")),
                                      column(width = 1, offset = 9, actionLink("link_to_tabpanel_C", "Next")))
                           ),

                           tabPanel(title = "C", #value = "intro_page",
                                    p(paste("Panel C")),
                                    fluidRow(
                                      column(width = 1, offset = 0, actionLink("link_to_tabpanel_B", "Previous")))
                           )
                )
)

server <- function(input, output, session) {

  observeEvent(input$link_to_tabpanel_A, {
    newvalue <- "A"
    updateNavbarPage(session, "panels_main", newvalue)
  }) 

  observeEvent(input$link_to_tabpanel_B, {
    newvalue <- "B"
    updateNavbarPage(session, "panels_main", newvalue)
  }) 

  observeEvent(input$link_to_tabpanel_C, {
    newvalue <- "C"
    updateNavbarPage(session, "panels_main", newvalue)
  }) 
}

shinyApp(ui = ui, server = server)

Notice that when you run the app you can navigate from A to B to C using the next button, but only the B to A previous button works. The C to B previous button does not work. Does anyone know why that is and have a suggestion on how to fix it?

As an aside, I have also tried a similar approach using updateTabsetPanel and run into the same problem so I suspect the underlying issue of my implementation is the same for both functions.


Solution

  • Two input elements cannot have the same inputId. Try changing link_to_tabpanel_B for the second link to link_to_tabpanel_B1. I have modified your code to do exactly that. Have a look:

     library(shiny)
    
      ui <- fluidPage(
        navbarPage(title = "",
                   id = "panels_main",
                   tabPanel(title = "A", #value = "intro_page",
                            p(paste("Panel A")),
                            fluidRow(column(width = 1, offset = 9, actionLink("link_to_tabpanel_B", "Next")))
    
                   ),
    
                   tabPanel(title = "B", #value = "intro_page",
                            p(paste("Panel B")),
                            fluidRow(
                              column(width = 1, offset = 0, actionLink("link_to_tabpanel_A", "Previous")),
                              column(width = 1, offset = 9, actionLink("link_to_tabpanel_C", "Next")))
                   ),
    
                   tabPanel(title = "C", #value = "intro_page",
                            p(paste("Panel C")),
                            fluidRow(
                              column(width = 1, offset = 0, actionLink("link_to_tabpanel_B1", "Previous")))
                   )
        )
      )
    
      server <- function(input, output, session) {
    
        observeEvent(input$link_to_tabpanel_A, {
          newvalue <- "A"
          updateNavbarPage(session, "panels_main", newvalue)
        }) 
    
        observeEvent(input$link_to_tabpanel_B ,{
          newvalue <- "B"
          updateNavbarPage(session, "panels_main", newvalue)
        }) 
    
        observeEvent( input$link_to_tabpanel_B1,{
          newvalue <- "B"
          updateNavbarPage(session, "panels_main", newvalue)
        }) 
    
        observeEvent(input$link_to_tabpanel_C, {
          newvalue <- "C"
          updateNavbarPage(session, "panels_main", newvalue)
        }) 
      }
    
      shinyApp(ui = ui, server = server)
    

    Hope it helps!