Are tabs with their own sidebars and mainPanels possible in shiny?

If I do not misunderstand your question, I think you can even evade the jQuery part (from @f1r3br4nd answer) by supplying an id for the tabsetPanel function, here id = "conditionedPanels". The value parameter (i.e. which tab is selected in the main panel) is then available via the input variable.

A minmal example: server.R may be empty except for the shinyServer function skeleton. The ui.R file might be as follows.

shinyUI(pageWithSidebar(
  headerPanel("Conditional Panels"),
  sidebarPanel(
    conditionalPanel(condition="input.conditionedPanels==1",
                     helpText("Content Panel 1")
    ),
    conditionalPanel(condition="input.conditionedPanels==2",
                     helpText("Content Panel 2")
    ) 
  ),
  mainPanel(
    tabsetPanel(
      tabPanel("Panel 1", value=1), 
      tabPanel("Panel 2", value=2)
      , id = "conditionedPanels"
    )
  )
))

I know this is an old post but I stumbled across it when I was looking for an answer to a similar question. I think you can also accomplish what you want by using a fluidPage (instead of pageWithSidebar) and then using the sidebarLayout function in each of the tabPanels.

An example:

library(shiny)

ui <- fluidPage(
  headerPanel("Header"),
  tabsetPanel(
    tabPanel('Tab 1',
             sidebarLayout(
               sidebarPanel(
                 selectInput("var", "Parametre", choices = c("1", "2", "3"))
               ),
               mainPanel(
                 textOutput("text1")
               )
             )  
    ),
    tabPanel('Tab 2',
             sidebarLayout(
               sidebarPanel(
                 selectInput("var", "Parametre", choices = c("21", "22", "23"))
               ),
               mainPanel(
                 textOutput("text2")
               )
             )
    )
  )
)

server <- function(input, output) {}

shinyApp(ui, server)

I got mine to work by having only one sidebarPanel like in the Shiny example apps but then wrapping stuff in the sidebarPanel that's only for specific tabs in separate conditionalPanel calls as here. The trick is then to make the character string that is conditionalPanel's condition argument be a jQuery statement that looks at the html attribute of the currently selected tab and ===s it to the name of the tab for which this content should appear in the sidebar:

conditionalPanel(
    "$('li.active a').first().html()==='Foo'",
    actionButton("bar","Bar"));

...where Foo is the title of the tab.

In short, one sidebar but its content conditional on active tab.

Tags:

R

Shiny