4

I'm using modules within my shiny app to display the content of different tabPanels. I would like to be able to travel to the second tab by clicking one button. I have the following code:

library(shiny)
library(shinydashboard)

moduleUI <- function(id){

  ns <- NS(id)
  sidebarPanel(
    actionButton(ns("action1"), label = "Go to tab 2")
  )
}

module <- function(input, output, session, openTab){

  observeEvent(input$action1, {
    openTab("two")
  })

  return(openTab)
}

ui <- fluidPage(
  navlistPanel(id = "tabsPanel",
               tabPanel("one", moduleUI("first")),
               tabPanel("two", moduleUI("second"))
  ))

server <- function(input, output, session){
  openTab <- reactiveVal()
  openTab("one")

  openTab <- callModule(module,"first", openTab)
  openTab <- callModule(module,"second", openTab)

  observeEvent(openTab(), {
    updateTabItems(session, "tabsPanel", openTab())
  })
}

shinyApp(ui = ui, server = server)

However this only works once. The problem I think, is that the module does not know when a tab is changed in the app. Therefore I'm looking for a way to make sure the module knows which tab is opened so that the actionButton works more that once. I have considered using input$tabsPanel but I don't know how to implement it. Help would be greatly appreciated.

MaxPlank
  • 185
  • 2
  • 13
  • you can enclose your `tabPanel` inside `div` and assign an id to `div`, this way you can know which `tab` is accessed – parth Jul 20 '17 at 11:19

1 Answers1

3

The problem is that once the user manually switches back to tab 1, the openTab() does not get updated. So therefore, when you click the actionButton a second time, openTab changes from "two" to "two" (i.e. it stays the same), and therefore your observeEvent is not triggered.

You could add:

  observeEvent(input$tabsPanel,{
    openTab(input$tabsPanel)
  })

So the openTab reactiveVal is updated also when a user manually changes back to tab1 (or any other tab).


You don't need modules to do what you want by the way, but I assume you have a specific reason to use them. For anyone else who wants to achieve the same but does not need modules:

library(shiny)
library(shinydashboard) 

ui <- fluidPage(
  sidebarPanel(
    actionButton(ns("action1"), label = "Go to tab 2")),
  navlistPanel(id = "tabsPanel",
               tabPanel("one"),
               tabPanel("two")
  ))

server <- function(input, output, session){ 
  observeEvent(input$action1, {
    updateTabItems(session, "tabsPanel", "two")
  })
}

shinyApp(ui = ui, server = server)
Florian
  • 24,425
  • 4
  • 49
  • 80
  • Thank you very much Florian! This helps a lot! Yes indeed this was only an example to illustrate my problem and not my actual app. – MaxPlank Jul 20 '17 at 13:08