Search code examples
rshinymoduleshinydashboard

How to switch between shiny tab panels from inside a module?


I'm trying to modularize a shiny app that has a button to reactively switch between tabPanels using updateTabsetPanel(). This works in the non-modular app, but doesn't when making the reactive is contained in a module. I think it has to do with the panels being outside the scope of the module. Below are minimal examples (the non-modular version that works and the modular version that does not). Is there a way to have the module talk to the tabPanels?

# Non-modular version
library(shiny)
library(shinydashboard)

ui <- fluidPage(
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1", 
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3, 
                       actionButton("switchbutton", "Click to swtich")
                   )
                 )
        ),
        tabPanel("T2", value = "2", 
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
)

server <-  function(input, output, session) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

shinyApp(ui, server)

# Modular version
library(shiny)
library(shinydashboard)

switcherButton <- function(id) {
  ns <- NS(id)
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1", 
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3, 
                       actionButton(ns("switchbutton"), "Click to switch")
                   )
                 )
        ),
        tabPanel("T2", value = "2", 
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
}

switcher <- function(input, output, session, parent) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

ui <- fluidPage(
  switcherButton("switcher1")
)

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

  callModule(switcher, "switcher1")

}

shinyApp(ui, server)

I


Solution

  • You have forgotten to wrap the tabBox id in ns(). Just replace "tabset2" by ns("tabset2")