Reputation: 1
I am working on a complex shiny application. The sidebarMenu contains over 100 menu items, with some nested items. I am also using modules (callModule) to generate repeated content.
The problem I am running into is the initial loading time, which is 28 seconds. When I ran profvis I found the time was adding up because the site is generating all of the tables, plots, and content for all 100+ menu items. Therefore, I would like to generate the content when the user clicks on the menu item rather than generating it all when the site is loaded.
I am using renderUI to create the tabItems and renderMenu to create the menuItems in the server.R file.
In the small reproducible example provided below, I set my sidebarMenu id to "smenu". I call input$smenu in tabItem to set the tabName. This doesn't work as expected. If you run the example, you will notice that if you 1) click on "Dashboard", 2) click on "Dashboard2", the h3() content that should appear on the dashboard2 page does not appear. However, if you 3) click on "Dashboard" again, and 4) click on "Dashboard2" again, the content appears.
I have two questions. 1) What is the best way to generate only the content that the user asks for rather than generating it all when the site is initially loaded?
2) Why does this code show content after this sequence of clicks rather than when the user first clicks on Dashboard2?
Thanks in advance for any advice or pointers.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "smenu",
sidebarMenuOutput("menu")
)
),
dashboardBody(
textOutput("testmenu"),
uiOutput("bodyUI")
)
)
server <- function(input, output) {
observe({
output$testmenu <- renderText({
out <- paste("Current menu item is", input$smenu, sep = " ")
})
})
output$bodyUI <- renderUI({
tabItems(
tabItem(tabName = input$smenu,
h3(paste("Hello World! You are on the", input$smenu, "menu item.", sep = " "))
)
)
})
output$menu <- renderMenu({
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard"),
menuItem("Dashboard2", tabName = "dashboard2", icon = icon("dashboard")),
menuItem("Dashboard3", tabName = "dashboard3", icon = icon("dashboard"))
)
)
})
}
shinyApp(ui, server)
Upvotes: 0
Views: 844
Reputation: 19544
If you want to use tabName
from menuItem
you have to define one tab per tabName:
tabItems(
tabItem(tabName = "dashboard",
h3(paste("Hello World! You are on the", input$smenu, "menu item.", sep = " "))
),
tabItem(tabName = "dashboard2",
h3(paste("Hello World! You are on the", input$smenu, "menu item.", sep = " "))
),
tabItem(tabName = "dashboard3",
h3(paste("Hello World! You are on the", input$smenu, "menu item.", sep = " "))
)
)
This will display the tabs after the first menu selection (since the tabs are defined in the server)
Also you should move the menu id
to the renderMenu
:
output$menu <- renderMenu({
sidebarMenu(id = "smenu",
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard"),
menuItem("Dashboard2", tabName = "dashboard2", icon = icon("dashboard")),
menuItem("Dashboard3", tabName = "dashboard3", icon = icon("dashboard"))
)
)
})
and simplify the ui
:
...
dashboardSidebar(
sidebarMenuOutput("menu")
),
...
Upvotes: 0