In the example below, there are two menuItems (1 and 2) and a menuSubItem (2.1) thats nested within menuItem 2. Each menuItem has a corresponding tabItem with a box, where the boxtitle is the name of the menuItem. If i run this app "Menu 1" is initally selected and shows the box called "1". If i than click on "Menu 2" the menuSubItem expands, but the body does not change at all.
I don't think that this is the normal behaviour, is there a way to fix this?
And a second question. If I have selected "Menu 2.1" and click on "Menu 1" why does the nested menuItem do not collapse again?
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(disable=TRUE),
dashboardSidebar(
sidebarMenu(
menuItem(
"Menu 1",
tabName="menu1"
),
menuItem(
"Menu 2",
tabName = "menu2",
menuSubItem(
"Menu 2.1",
tabName = "menu2_1"
)
)
)
),
dashboardBody(
tabItems(
tabItem(tabName="menu1",
box("1")
),
tabItem(tabName="menu2",
box("2")
),
tabItem(tabName="menu2_1",
box("2.1")
)
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
The behaviour you see is normal, see here
Childless menuItem()s/menuSubItem()s must be given a tabName argument
Childfull” menuItem()s cannot have a tabName or a selected argument
(or rather, they can, but this will be completely ignored by Shiny).
Instead, at most, one of them can take a startExpanded = TRUE, which
tells Shiny to start out with that menuItem() expanded, i.e. revealing
all its children
You can access the expanded tab with my code below, so you can create behavior based on that, but I do not think it is possible to display a page when clicking a menuItem that has children.
Hope this helps!
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(disable=TRUE),
dashboardSidebar(
sidebarMenu(
menuItem(
"Menu 1",
tabName="menu1"
),
menuItem(
"Menu 2",
expandedName = "menu2",
menuItem(
"Menu 2.1",
tabName = "menu2_1"
)
)
),
textOutput('selectedmenu')
),
dashboardBody(
tabItems(
tabItem(tabName="menu1",
box("1")
),
tabItem(tabName="menu2",
box("2")
),
tabItem(tabName="menu2_1",
box("2.1")
)
)
)
)
server <- function(input, output) {
output$selectedmenu <- renderText({
print(input$sidebarItemExpanded)
})
}
shinyApp(ui = ui, server = server)
Change first tab when menu 2 is expanded, request from comment:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(disable=TRUE),
dashboardSidebar(
sidebarMenu(id="mysidebar",
menuItem(
"Menu 1",
tabName="menu1"
),
menuItem(
"Menu 2",
expandedName = "menu2",
menuItem(
"Menu 2.1",
tabName = "menu2_1"
)
)
)
),
dashboardBody(
tabItems(
tabItem(tabName="menu1",
box("1")
),
tabItem(tabName="menu2",
box("2")
),
tabItem(tabName="menu2_1",
box("2.1")
)
)
)
)
server <- function(input, output,session) {
observeEvent(input$sidebarItemExpanded, {
updateTabItems(session,"mysidebar","menu2_1")
})
}
shinyApp(ui = ui, server = server)
Related
This is my {shinydashboard}:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
"User Name",
subtitle = a(href = "#", icon("circle", class = "text-success"), "Online"),
sidebarMenu(
id = "tabs",
menuItem(
"Dashboard",
tabName = "dashboard",
icon = icon("dashboard"),
menuSubItem(
"Widgets",
icon = icon("th"),
tabName = "widgets"
),
menuSubItem(
"Charts",
icon = icon("th"),
tabName = "charts"
)
))),
dashboardBody(
tabItems(
tabItem("dashboard",
tags$button(
h1('This button takes me to the Widgets Panel')),
br(),
br(),
tags$button(h1('This button takes me to the Charts Panel'))
))))
server = function(input, output) {
}
shinyApp(ui, server)
The idea is to click on 'Dashboard' Menu and then on the body I have a link or button that takes me to the 'Widgets' or 'Charts' Panels.
Once I click on those buttons/links OR click on the Sub Menus of 'Dashboard' menu these actions will take me to their Panels.
So, how can I add the buttons and links that take me to the panels of my Menu SubItems?
And how can I add the buttons and links on the body of my Shiny Dashboard?
Any help would me amazing.
Your question is the result of a common misunderstanding regarding shinydashboard's structure.
Childfull menuItems (like your "Dashboard" menuItem) don't have a corresponding tabItem.
The only usecase for a childfull menuItem is to expand on click and present its children (no visual change in the body - only in the sidebar).
Accordingly in your above code the tabName = "dashboard" parameter is ignored and the tabItem("dashboard", ...) isn't displayed.
When a menuItem is childfull it accepts the parameters
expandedName and startExpanded.
When a menuItem is childless it accepts the parameters tabName
and selected (just like menuSubItem which always is childless).
Please read the small print.
Also check my related answers here and here.
However, there are unofficial workarounds to have a childfull menuItem display a tabItem - I don't recommend to use them.
To navigate your tabs programmatically use updateTabItems:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
header = dashboardHeader(),
sidebar = dashboardSidebar(
sidebarUserPanel(name = "User Name",
subtitle = a(href = "#", icon("circle", class = "text-success"), "Online"),
image = NULL),
sidebarMenu(
id = "tabs",
menuItem(
"Dashboard",
menuSubItem("Widgets",
icon = icon("th"),
tabName = "widgets"),
menuSubItem("Charts",
icon = icon("th"),
tabName = "charts"),
icon = icon("dashboard"),
expandedName = "dashboard",
startExpanded = TRUE
)
)
),
body = dashboardBody(
tabItems(
tabItem("widgets", actionButton("goCharts", "Go to Charts tab")),
tabItem("charts", actionButton("goWidgets", "Go to Widgets tab"))
)
)
)
server <- function(input, output, session) {
observeEvent(input$goCharts, {
updateTabItems(session, inputId = "tabs", selected = "charts")
})
observeEvent(input$goWidgets, {
updateTabItems(session, inputId = "tabs", selected = "widgets")
})
}
shinyApp(ui, server)
In my shinydashboard app, I want to specify a different tabName in the sidebarMenu from the tabName in the body. The server function should then catch the tabName on click and call updateTabItems.
The idea is, that some menu items in the sidebar should go to the same tab, and the longer tabName in the sideBar contains additional information used to fill the tab.
When both tabNames in sideBar and tabItems are the same, the code works. However, if I change the tabName in the sideBar, e.g. to one_param_val, updateTabItems stops working.
Any ideas why that is and what I can do about it?
library(shiny)
library(shinydashboard)
ui <- shinydashboardPlus::dashboardPage(
header=shinydashboard::dashboardHeader(title = "Switch tabs"),
sidebar=shinydashboard::dashboardSidebar(
shinydashboard::sidebarMenu(id = "tabs",
shinydashboard::menuItem(
"Menu Item 1", tabName = "one_param_val" # works for tabName="one"
),
shinydashboard::menuItem(
"Menu Item 2", tabName = "two"
)
)
),
body=shinydashboard::dashboardBody(
shinydashboard::tabItems(
shinydashboard::tabItem(
tabName = "one", h2("Content One")
),
shinydashboard::tabItem(
tabName = "two", h2("Content Two")
)
)
)
)
server <- function(input, output, session) {
shiny::observeEvent(input$tabs, {
if(grepl("^one", input$tabs)) {
message("switching to one")
shinydashboard::updateTabItems(
session, inputId="tabs", selected="one"
)
}
})
}
shinyApp(ui, server)
Here is a workaround using a hidden menuItem. However the proxy menuItem will no longer get marked as selected in the sidebar:
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- shinydashboardPlus::dashboardPage(
header=shinydashboard::dashboardHeader(title = "Switch tabs"),
sidebar=shinydashboard::dashboardSidebar(
shinydashboard::sidebarMenu(id = "tabs",
shinyjs::hidden(shinydashboard::menuItem(
"Menu Item 1", tabName = "one"
)),
shinydashboard::menuItem(
"Menu Item 1", tabName = "one_param_val"
),
shinydashboard::menuItem(
"Menu Item 2", tabName = "two"
)
)
),
body=shinydashboard::dashboardBody(
useShinyjs(),
shinydashboard::tabItems(
shinydashboard::tabItem(
tabName = "one", h2("Content One")
),
shinydashboard::tabItem(
tabName = "two", h2("Content Two")
)
)
)
)
server <- function(input, output, session) {
shiny::observeEvent(input$tabs, {
# browser()
if(grepl("^one", input$tabs)) {
message("switching to one")
shinydashboard::updateTabItems(
session, inputId="tabs", selected="one"
)
}
})
}
shinyApp(ui, server)
I'm using a shinydashboard but when the title is too long it fails to wrap the lines. I have tried using <br/> to accomplish this, but it doesn't work even with HTML() around it in this context.
I know I can make the title space wider with titleWidth, but that does not look as good in many cases.
What would be the simplest way to achieve this?
Here's an example:
library(shiny)
library(shinydashboard)
## Only run this example in interactive R sessions
if (interactive()) {
header <- dashboardHeader(title = "This title is just way too long")
sidebar <- dashboardSidebar(
sidebarUserPanel("User Name",
subtitle = a(href = "#", icon("circle", class = "text-success"), "Online"),
# Image file should be in www/ subdir
image = "userimage.png"
),
sidebarSearchForm(label = "Enter a number", "searchText", "searchButton"),
sidebarMenu(
# Setting id makes input$tabs give the tabName of currently-selected tab
id = "tabs",
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Widgets", icon = icon("th"), tabName = "widgets", badgeLabel = "new",
badgeColor = "green"),
menuItem("Charts", icon = icon("bar-chart-o"),
menuSubItem("Sub-item 1", tabName = "subitem1"),
menuSubItem("Sub-item 2", tabName = "subitem2")
)
)
)
body <- dashboardBody(
tabItems(
tabItem("dashboard",
div(p("Dashboard tab content"))
),
tabItem("widgets",
"Widgets tab content"
),
tabItem("subitem1",
"Sub-item 1 tab content"
),
tabItem("subitem2",
"Sub-item 2 tab content"
)
)
)
shinyApp(
ui = dashboardPage(header, sidebar, body),
server = function(input, output) { }
)
}
The goal is to apply word-wrapping so that we can read the entire title (which says "This title is just way too long").
header <- dashboardHeader(title = h4(HTML("This title<br/>is just way too long")))
shinyApp(
ui = dashboardPage(header, sidebar, body),
server = function(input, output) { }
)
I would like to greet the user of my app with a modal once they click on a specific menuItem in the sidebar of my ShinyDashboard. Here's a simple recreation of my previous attempt:
# libraries
library(shiny)
library(shinydashboard)
## UI ##
ui <- dashboardPage(
skin = "black",
dashboardHeader(),
dashboardSidebar(
sidebarMenu(id = "sidebarmenu",
menuItem("Dashboard", tabName = "dashboard"),
menuItem("Subitems", tabName = "subitems",
menuSubItem("Upload", "upload"),
menuSubItem("Browse", "browse")
),
menuItem("Widgets", tabName = "widgets")
)
),
dashboardBody(
uiOutput('tab')
)
)
## server ##
server <- function(input, output) {
output$tab <- renderUI({
paste("The selected tab is", input$sidebarmenu)
})
observeEvent(input$sidebarmenu == "widgets", {
showModal(
modalDialog(title = "You selected Widgets", "Or did you?")
)
})
}
shinyApp(ui, server)
The goal is to open the modal only when the menuItem widgets is selected. Despite the condition input$sidebarmenu == "widgets", this does not happen. Rather, the modal is displayed any time the user switches menuItems. Why is this the case and how can I do this properly?
Thank you in advance for any input.
Add this to the observeEvent
observeEvent(input$sidebarmenu, {
req(input$sidebarmenu == "widgets")
showModal(
modalDialog(title = "You selected Widgets", "Or did you?")
)
})
(cross post from shiny google groups, https://groups.google.com/forum/#!topic/shiny-discuss/CvoABQQoZeE)
How can one navigate to a particular sidebar menu item in ShinyDashboard?
sidebarMenu(
menuItem("Menu Item 1")
menuItem("Menu Item 2")
)
i.e. how can I put a button on the "Menu Item 1" page that will link to "Menu Item 2"?
To navigate between tabs I am using the updateTabsetPanel function:
observeEvent(input$go,{
updateTabsetPanel(session, "tabset1", selected = "Step 2")
})
I believe I should be able to use a similar function to navigate to a sidebar menu, but I am not sure what that is.
Any pointers greatly appreciated
Thanks
Iain
Is this what you are looking for? note that the example is taken from Change the selected tab on the client
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Simple tabs"),
dashboardSidebar(
sidebarMenu(id = "tabs",
menuItem("Menu Item 1", tabName = "one", icon = icon("dashboard")),
menuItem("Menu Item 1", tabName = "two", icon = icon("th"))
)
),
dashboardBody(
tabItems(
tabItem(tabName = "one",h2("Dashboard tab content"),actionButton('switchtab', 'Switch tab')),
tabItem(tabName = "two",h2("Widgets tab content"))
)
)
)
server <- function(input, output, session) {
observeEvent(input$switchtab, {
newtab <- switch(input$tabs, "one" = "two","two" = "one")
updateTabItems(session, "tabs", newtab)
})
}
shinyApp(ui, server)