Search code examples
rshinyshiny-servershinydashboard

Shiny dashboardSidebar change when different tabItem selected


I am having a following problem:

I want a sidebar change when I switch between tabItem(s).

dashboardPage(
dasboardHeader(title = ""),
dashboardSidebar(
  sidebarMenu(
    menuItem("1", tabName = "1"),
    menuItem("2", tabName = "2")     
             ),
#I want this to be displayed when menuItem "1" is clicked
      tabsetPanel(
            tabPanel("t1", val="t1",
                    .... some inputs),
            tabPanel("t2", val="t2",
                    .... some inputs)
                 ),
 # This to be displayed when menuItem "2" is clicked    
      selectInput("s1", label="Select"....),
      selectInput("s2", label="Select2"...)
  )
dashboardBody(
 tabItem(tabName="1", 
      .......
   ),
 tabItem(tabName="2",
      ........
   )
 )
)

I have the dashboardBody changing when switching between the tabs but don't know how to change the dashboardSidebar values. Tried this inside the dashboardSidebar:

 conditionalPanel(
             condition="tabName='1'",
          #displaying first version of DashboardSidebar
             ),
 conditionalPanel(
             condition="tabName='2'",
          #displaying second version of DashboardSidebar
             )

But it didn't work for me.

Any ideas?

Thank you for your help.


Solution

  • First of all, you have to add sidebarMenu an ID which will be used for a Shiny input value, and it will report which tab is selected.

    After that, add uiOutput to dashboardSidebar function.

    uiOutput is going to receive, depending on a selected tab, either tabsetPanel or two selectInputs.

    Finally, within renderUI, which you define on the server side, you just need to create conditional statements. That's the easy part.

    The tricky part is that you have to wrap selectInputs into a list - otherwise only the second widget would be sent to the UI. Even more tricky part is that you have to specify the ID of tabsetPanel when you want to send it to the UI via renderUI. (That's very tricky because normally you don't have to specify its ID!)


    Full example:

    library(shiny)
    library(shinydashboard)
    rm(ui)
    rm(server)
    
    ui <- dashboardPage(
        dashboardHeader(title = ""),
        dashboardSidebar(
    
        # added ID which will be used for a Shiny input value,
        # and it will report which tab is selected.
        sidebarMenu(id = "tab", 
          menuItem("1", tabName = "1"),
          menuItem("2", tabName = "2")
        ),
        uiOutput("out1")
        ),
        dashboardBody(
          tabItem(tabName = "1"),
          tabItem(tabName = "2")
        )
    )
    
    server <- function(input, output) {
    
    
      output$out1 <- renderUI({
    
        if (input$tab == "1") {
    
          dyn_ui <- tabsetPanel(id = "tabset_id", selected = "t1", 
                                tabPanel("t1", value = "t1"),
                                tabPanel("t2", value = "t2"))
    
        } 
        if (input$tab == "2") {
    
          dyn_ui <- list(selectInput("s1", label = "Select", choices = letters[1:3]),
                         selectInput("s2", label = "Select2", choices = letters[4:6]))
        }
        return(dyn_ui)
      })
    }
    
    shinyApp(ui, server)