sidebarItemExpanded only works when tab is closed, not when switching tabs

Cross-posted to Stack Overflow

Hi everyone,
I'm working on a shiny dashboard and trying to get the right sidebar to show different content based on which childfull left sidebar menu item is expanded.

I've read several SO posts and info in the shinydashboard documentation about the behavior of childfull menuItems, how to use input$sidebarItemExpanded, etc., but frankly I find it all very confusing and although I've tried several things, I haven't been able to solve this particular problem.

The problem is: after the first time you switch menuItems, the content in the right sidebar changes only when you click a second time on the currently-expanded menuItem to close it before clicking to expand a different menuItem.

If instead you just click from menuItem 1 to menuItem 2, the first menuItem will visually shrink when the other one expands, but apparently the value of input$sidebarItemExpanded doesn't change until you manually "deselect" the first menuItem. This is really not intuitive for the user, so I'm looking for a way to get around it.

Here is an example app:

library(shiny)
library(shinydashboardPlus)

# convertMenuItem function, from https://stackoverflow.com/questions/31794702/r-shiny-dashboard-tabitems-not-apparing
convertMenuItem <- function(mi,tabName) {
  mi$children[[1]]$attribs['data-toggle']="tab"
  mi$children[[1]]$attribs['data-value'] = tabName
  mi
}


ui <- tags$body(class = "skin-blue sidebar-mini control-sidebar-open", tagList(dashboardPagePlus(
  header = dashboardHeaderPlus(
    title = "Animals",
    enable_rightsidebar = TRUE,
    rightSidebarIcon = "paw"
  ),
  
  body = dashboardBody(),
  
  rightsidebar = rightSidebar(
    uiOutput("rightSidebar") # We'll define this dynamically using renderUI in the server
  ),
  
  ## Left sidebar
  sidebar = dashboardSidebar(
    sidebarMenu(
      # Cats menu item
      convertMenuItem(menuItem(expandedName = "cats", text = "Cats", 
                               tabName = "cats", icon = icon("cat"),
                               startExpanded = TRUE,
                               class = "active",
                               h4("CAT CONTENT"),
                               selectInput("catSelector", label = "Select a cat",
                                           choices = c("American Shorthair", "Ragdoll", 
                                                       "Bengal", "Siamese", "Sphynx"))
      ), tabName = "cats"
      ),
      convertMenuItem(menuItem(expandedName = "dogs", text = "Dogs", 
                               tabName = "dogs", icon = icon("dog"),
                               class = "active",
                               h4("DOG CONTENT"),
                               selectInput("dogSelector", label = "Select a dog",
                                           choices = c("German Shepherd", "Poodle", 
                                                       "Chihuahua", "Husky", "Pitbull"))
      ), tabName = "dogs"
      )
    )
  )
),

)
)

server <- function(input, output, session){
  
  # RIGHT MENU BAR CONTROLS -------------------------------------------------
  observeEvent(input$sidebarItemExpanded, {
    if(input$sidebarItemExpanded == "cats"){
      message("Cats view has been selected")
      output$rightSidebar <- renderUI({
        rightSidebar(
          ### Right sidebar cat content
          rightSidebarTabContent(
            title = "Cat stuff",
            id = "catStuff",
            active = T,
            icon = "cat",
            p("Here is some information about cats.")
          )
        )
      })
    }else if(input$sidebarItemExpanded == "dogs"){
      message("Dogs view has been selected")
      output$rightSidebar <- renderUI({
        rightSidebar(
          ### Right sidebar dog content
          rightSidebarTabContent(
            title = "Dog stuff",
            id = "dogStuff",
            active = T,
            icon = "dog",
            p("Here is some information about dogs.")
          )
        )
      })
    }
  })
}

shinyApp(ui = ui, server = server)

If it's helpful, here is a screen recording where I demonstrate the problem. You can see that the app opens with the "cat" tab expanded, and there is cat-related content in the right sidebar. Then, if I click the "dog" tab, the content in the right sidebar updates appropriately. But then, if I try to go back to the "cat" tab, the right sidebar content doesn't update unless I click a second time on the "dog" tab to "close" it, even though it already looks closed to the user.

I would be grateful for any pointers on this--thank you very much!

I think I've fixed it, thanks to a solution by @ismirsehregal from Stack Overflow a while back.

Here's the new code (have to load shinyjs and use hidden menuItems):

library(shiny)
library(shinydashboardPlus)
library(shinyjs)
ui <- tags$body(class = "skin-blue sidebar-mini control-sidebar-open", tagList(dashboardPagePlus(
  header = dashboardHeaderPlus(
    title = "Animals",
    enable_rightsidebar = TRUE,
    rightSidebarIcon = "paw"
  ),
  
  body = dashboardBody(useShinyjs()),
  
  rightsidebar = rightSidebar(
    uiOutput("rightSidebar") # We'll define this dynamically using renderUI in the server
  ),
  
  ## Left sidebar
  sidebar = dashboardSidebar(
    sidebarMenu(
      id = "sidebarID",
      # Cats menu item
      menuItem(expandedName = "cats", text = "Cats", 
                               tabName = "cats", icon = icon("cat"),
                               startExpanded = TRUE,
                               class = "active",
                               h4("CAT CONTENT"),
                               selectInput("catSelector", label = "Select a cat",
                                           choices = c("American Shorthair", "Ragdoll", 
                                                       "Bengal", "Siamese", "Sphynx"))),
      hidden(menuItem("hiddenCats", tabName = "hiddenCats")),
      menuItem(expandedName = "dogs", text = "Dogs", 
                               tabName = "dogs", icon = icon("dog"),
                               class = "active",
                               h4("DOG CONTENT"),
                               selectInput("dogSelector", label = "Select a dog",
                                           choices = c("German Shepherd", "Poodle", 
                                                       "Chihuahua", "Husky", "Pitbull"))),
      hidden(menuItem("hiddenDogs", tabName = "hiddenDogs"))
    )
  )
),

)
)

server <- function(input, output, session){
  
  # RIGHT MENU BAR CONTROLS -------------------------------------------------
  observeEvent(input$sidebarItemExpanded, {
    if(input$sidebarItemExpanded == "cats"){
      updateTabItems(session, "sidebarID", selected = "hiddenCats")
    }else if(input$sidebarItemExpanded == "dogs"){
      updateTabItems(session, "sidebarID", selected = "hiddenDogs")
    }
  })
  
  observeEvent(input$sidebarItemExpanded, {
    if(input$sidebarItemExpanded == "cats"){
      message("Cats view has been selected")
      output$rightSidebar <- renderUI({
        rightSidebar(
          ### Right sidebar cat content
          rightSidebarTabContent(
            title = "Cat stuff",
            id = "catStuff",
            active = T,
            icon = "cat",
            p("Here is some information about cats.")
          )
        )
      })
    }else if(input$sidebarItemExpanded == "dogs"){
      message("Dogs view has been selected")
      output$rightSidebar <- renderUI({
        rightSidebar(
          ### Right sidebar dog content
          rightSidebarTabContent(
            title = "Dog stuff",
            id = "dogStuff",
            active = T,
            icon = "dog",
            p("Here is some information about dogs.")
          )
        )
      })
    }
  })
}

shinyApp(ui = ui, server = server)

This solution was posted here and here. If you have more SO reputation than I do and this solution helps you, please go upvote @ismirsehregal's answer over there!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.