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.