Nested menuItems displaying content at each level

Hi,

I am playing with shinydashboard menuItems, trying to achieve a nested (branching) structure.

Lets say you have 3 levels Global (highest instance) - Regional (middle instance, multiple items) - Local (lowest instance, multiple items per each region).

By clicking on Global, you'd get global statistics + a menu for Regional items will roll down, enabling you to click on Regional items. By clicking on one of the Regional items, you'd get regional statistics (for a given region) + a menu for Local items will roll down... A simple example would look like this:

library(shiny)
library(shinydashboard)

header <- dashboardHeader()

sidebar = dashboardSidebar(
  sidebarMenu(
    id = "tabs",
    menuItem("Global", tabName = "global",
                             menuItem("Regional_1", tabName = "regional_1",
                                      menuSubItem("Local_1_1", tabName = "local_1_1"),
                                      menuSubItem("Local_1_2", tabName = "local_1_2"),
                                      selected = TRUE),
                             menuItem("Regional_2", tabName = "regional_2",
                                      menuSubItem("Local_2_1", tabName = "local_2_1"),
                                      menuSubItem("Local_2_2", tabName = "local_2_2"),
                                      selected = TRUE),
             selected = TRUE
    )
  )
)

body = dashboardBody(
  tabItems(
    tabItem("global", "global"),
    tabItem("regional_1", "regional_1"),
    tabItem("regional_2", "regional_2"),
    tabItem("local_1_1", "local_1_1"),
    tabItem("local_1_2", "local_1_2"),
    tabItem("local_2_1", "local_2_1"),
    tabItem("local_2_2", "local_2_2")
  )
)

shinyApp(
  ui = dashboardPage(header, sidebar, body),
  server = function(input, output) { }
)

The problem is, that with this structure, the content is only displayed for the terminal nodes (lowest level items). SO answer offers a solution for 2 level structure by wrapping the higher level with a custom function:


convertMenuItem <- function(mi,tabName) {
 mi$children[[1]]$attribs['data-toggle']="tab"
 mi$children[[1]]$attribs['data-value'] = tabName
 if(length(mi$attribs$class)>0 && mi$attribs$class=="treeview"){
   mi$attribs$class=NULL
 }
 mi
}



header <- dashboardHeader()

sidebar = dashboardSidebar(
 sidebarMenu(
   id = "tabs",
   convertMenuItem(menuItem("Global", tabName = "global",
                            menuItem("Regional_1", tabName = "regional_1",
                                     menuSubItem("Local_1_1", tabName = "local_1_1"),
                                     menuSubItem("Local_1_2", tabName = "local_1_2")),
                            menuItem("Regional_2", tabName = "regional_2",
                                     menuSubItem("Local_2_1", tabName = "local_2_1"),
                                     menuSubItem("Local_2_2", tabName = "local_2_2"))
   ),
   "global"
   )
 )
)

body = dashboardBody(
 tabItems(
   tabItem("global", "global"),
   tabItem("regional_1", "regional_1"),
   tabItem("regional_2", "regional_2"),
   tabItem("local_1_1", "local_1_1"),
   tabItem("local_1_2", "local_1_2"),
   tabItem("local_2_1", "local_2_1"),
   tabItem("local_2_2", "local_2_2")
 )
)

shinyApp(
 ui = dashboardPage(header, sidebar, body),
 server = function(input, output) { }
)

Sadly, it is not possible to simply wrap both Global level and Regional levels with this function. I don't know exactly what is going on in the function, so it is hard for me to judge whether a simple modification of the convertMenuItem function would be enough for it to work properly on all levels, or whether more complex solution is needed.

Thanks for any help.

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