rshiny

Hide tab in Shiny module


This question is in reference to my previous question which was kindly answered very quickly by another user.

Here is my new code, showing a very simple module structure:

moduleUI <- function(id) {
  ns <- NS(id)
  
  sidebarLayout(
    sidebarPanel = sidebarPanel(
      checkboxInput(ns("checkboxInput1Id"), "Check to show first tab"),
      conditionalPanel(
        style = "display: none;",
        "input.checkboxInput1Id == true",
        checkboxInput(ns("checkboxInput2Id"), "Check to show second set of tabs"),
        ns = ns
      )
    ),
    
    mainPanel = mainPanel(
      conditionalPanel(
        style = "display: none;",
        "input.checkboxInput1Id == true", 
        tabsetPanel(
          id = ns("tabs"),
          tabPanel("Tab 1", plotOutput(ns("plot1")), value = ns("Tab 1")),
          tabPanel("Tab 2", plotOutput(ns("plot2")), value = ns("Tab 2"))
        ),
        ns = ns
      )
    )
  )
}

moduleServerImpl <- function(id) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    x <- iris$Sepal.Length
    y <- iris$Sepal.Width
    
    output$plot1 <- renderPlot(hist(islands))
    output$plot2 <- renderPlot(plot(x ~ y))
    
    observe({
      if (input$checkboxInput2Id) {
        showTab(inputId = ns("tabs"), target = ns("Tab 2"), session = session)
      } else {
        hideTab(inputId = ns("tabs"), target = ns("Tab 2"), session = session)
      }
    })
  }) 
}

ui <- fluidPage(
  moduleUI(id = "moduleNamespace")
)

server <- function(input, output, session) {
  moduleServerImpl(id = "moduleNamespace")
}

runApp(shinyApp(ui = ui, server = server))

I wish to hide Tab 2 unless checkboxInput2Id is ticked. This works in the non-modular case by simply removing all occurrences of NS and ns, respectively. However, I cannot get this to work in the modular case once I'm working around namespaces.


Solution

  • You don't want to namespace inputs or outputs in the server function - the whole point of namespacing is that you can refer to just the ID used in the UI.

    moduleUI <- function(id) {
      ns <- NS(id)
      
      sidebarLayout(
        sidebarPanel = sidebarPanel(
          checkboxInput(ns("checkboxInput1Id"), "Check to show first tab"),
          conditionalPanel(
            "input.checkboxInput1Id == true",
            checkboxInput(ns("checkboxInput2Id"), "Check to show second set of tabs"),
            ns = ns
          )
        ),
        
        mainPanel = mainPanel(
          conditionalPanel(
            "input.checkboxInput1Id == true", 
            tabsetPanel(
              id = ns("tabs"),
              tabPanel("Tab 1", plotOutput(ns("plot1")), value = "a"),
              tabPanel("Tab 2", plotOutput(ns("plot2")), value = "b")
            ),
            ns = ns
          )
        )
      )
    }
    
    moduleServerImpl <- function(id) {
      moduleServer(id, function(input, output, session) {
        
        x <- iris$Sepal.Length
        y <- iris$Sepal.Width
        
        output$plot1 <- renderPlot(hist(islands))
        output$plot2 <- renderPlot(plot(x ~ y))
        
        observe({
          if (input$checkboxInput2Id) {
            showTab(inputId = "tabs", target = "b", session = session)
          } else {
            hideTab(inputId = "tabs", target = "b", session = session)
          }
        })
      }) 
    }
    
    ui <- fluidPage(
      moduleUI(id = "moduleNamespace")
    )
    
    server <- function(input, output, session) {
      moduleServerImpl(id = "moduleNamespace")
    }
    
    runApp(shinyApp(ui = ui, server = server))