2

I have checked SO for similar posts and have not found this same or similar issue anywhere. My apologies if I missed something, however, I do believe this question has not been asked before.

What I would like to do is to show parts of my UI depending on user input / application output. A minimal working example of my situation is attached here:

ui <- fluidPage(
 sidebarLayout(
 sidebarPanel = sidebarPanel(
 checkboxInput("checkboxInput1Id", "Check to show first tab"),
 conditionalPanel(
 "input.checkboxInput1Id == true",
 checkboxInput("checkboxInput2Id", "Check to show second set of tabs")
 )
 ),
 
 mainPanel = mainPanel(
 conditionalPanel(
 "input.checkboxInput1Id == true", 
 tabsetPanel(
 tabPanel("Tab 1", plotOutput("plot1")),
 conditionalPanel(
 "input.checkboxInput2Id == true",
 tabsetPanel(
 tabPanel("Tab 2.1", plotOutput("plot2.1")),
 tabPanel("Tab 2.2", plotOutput("plot2.2")),
 tabPanel("Tab 2.3", plotOutput("plot2.3"))
 )
 )
 ))
 )
 )
 
)
server <- function(input, output, session) {
 x <- iris$Sepal.Length
 y <- iris$Sepal.Width
 z <- iris$Petal.Length
 
 output$plot1 <- renderPlot(hist(islands))
 output$plot2.1 <- renderPlot(plot(x ~ y))
 output$plot2.2 <- renderPlot(plot(x ~ z))
 output$plot2.3 <- renderPlot(plot(y ~ z))
}
runApp(shinyApp(ui=ui, server=server))

As one can see from the layout of my UI's mainPanel, I want the inner conditionalPanel to be part of the tabsetPanel which includes the first conditionalPanel. In other words:

  1. On app startup: only show sidebarPanel
  2. On selection of checkboxInput1Id: show checkboxInput2Id and show conditionalPanel #1
  3. On selection of checkboxInput2Id: show conditionalPanel #2 such that the three tabPanels contained appear next to Tab 1.

The problem I face is that this does not seem possible (or I am using the API incorrectly). The second set of tabs appears underneath my first tab and I cannot make it appear alongside the first tab. Any advice on how to fix this? Here is a screenshot of the app's look and an indication of where I want the tabs to appear:

enter image description here

Edit: referring to Ismirsehregal's answer, I am now finding it hard to hide a tab when working from a modularized context. My code is such as this:

ui <- function(id) {
 ns <- NS(id)
 sidebarLayout(
 sidebarPanel = sidebarPanel(...),
 mainPanel = mainPanel(
 conditionalPanel(
 style = "display: none;",
 condition = "input.someCondition == true",
 tabsetPanel(
 id = ns("foobar"),
 tabPanelFromModule(ns("moduleName")) # ns("moduleName") is the resulting tabPanel's value,
 someMoreTabPanels
 )
 )
 )
 )
}
server <- function(id) {
 moduleServer(id, function(input, output, session) {
 observe({
 hideTab(inputId=ns("foobar"), target=ns("moduleName"))
 }) %>% bindEvent(input$someInput)
 }
}

This should hide the tabPanel, but does not do so. I have checked the HTML code of my UI object and it looks like I am referring correctly to the tabsetPanel as well as the tabPanel held within.

asked Jun 11, 2025 at 7:04
1
  • 2
    I haven't investigated fully, but I think you will need to take another approach. The reason being that a tabsetPanel should contain tabPanels, not conditionalPanels. I expect you will need to use uiOutput/renderUI to generate the elements you want on the fly. Commented Jun 11, 2025 at 7:25

1 Answer 1

2

In this case I'd suggest using showTab and hideTab instead of conditionalPanel.

Please note: the tabsetPanel needs an id for this to work:


library(shiny)
ui <- fluidPage(
 sidebarLayout(
 sidebarPanel = sidebarPanel(
 checkboxInput("checkboxInput1Id", "Check to show first tab"),
 conditionalPanel(style = "display: none;",
 "input.checkboxInput1Id == true",
 checkboxInput("checkboxInput2Id", "Check to show second set of tabs")
 )
 ),
 
 mainPanel = mainPanel(
 conditionalPanel(style = "display: none;",
 "input.checkboxInput1Id == true", 
 tabsetPanel(id = "tabs",
 tabPanel("Tab 1", plotOutput("plot1")),
 tabPanel("Tab 2.1", plotOutput("plot2.1")),
 tabPanel("Tab 2.2", plotOutput("plot2.2")),
 tabPanel("Tab 2.3", plotOutput("plot2.3"))
 ))
 )
 )
 
)
server <- function(input, output, session) {
 x <- iris$Sepal.Length
 y <- iris$Sepal.Width
 z <- iris$Petal.Length
 
 output$plot1 <- renderPlot(hist(islands))
 output$plot2.1 <- renderPlot(plot(x ~ y))
 output$plot2.2 <- renderPlot(plot(x ~ z))
 output$plot2.3 <- renderPlot(plot(y ~ z))
 
 observeEvent(input$checkboxInput2Id, {
 if(isTRUE(input$checkboxInput2Id)){
 # showTab(inputId = "tabs", target = "Tab 2.1")
 lapply(list("Tab 2.1", "Tab 2.2", "Tab 2.3"), showTab, inputId = "tabs")
 } else {
 # hideTab(inputId = "tabs", target = "Tab 2.1")
 lapply(list("Tab 2.1", "Tab 2.2", "Tab 2.3"), hideTab, inputId = "tabs")
 }
 })
}
runApp(shinyApp(ui=ui, server=server))

Furthermore, I applied this fix to avoid the flashing of the conditionalPanel on app start.

Also related:

https://mastering-shiny.org/action-dynamic.html

answered Jun 11, 2025 at 7:46
Sign up to request clarification or add additional context in comments.

3 Comments

Amazing, this worked like a charm. Also thanks a lot for the fix mentioned, this had been bothering me for a while. Solved!
Unfortunately, another problem has popped up... for some reason, I fail to hide tabs once I'm in a modularized context. I have edited my original question. Do you think you could take another look and tell me what I'm missing? It would be much appreciated.
I'd suggest to post a follow-up question (and link it here) instead of modifying this one. Cheers. PS: are you aware of conditionalPanel's ns parameter?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.