Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure the shiny app knows which tab is currently opened when using modules?

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.

like image 561
MaxPlank Avatar asked Oct 20 '25 16:10

MaxPlank


1 Answers

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)
like image 130
Florian Avatar answered Oct 23 '25 06:10

Florian