8

I have created dynamic sibebar menus in R shinydashboard. Even though I use selected = TRUE, no menuItem associated with a menu gets selected at startup in this dynamic mode.

How can I make sure I have control on which menuItem's contents is shown at startup in this dynamic mode?

I have been searching all over through similar posts. Could not find anything that work so far. updateTabItems() did not seem to work.

Any ideas? thanks from advance.

library(shiny)
library(shinydashboard)
ui <- dashboardPage(
  dashboardHeader(title = "Dynamic sidebar"),
  dashboardSidebar(
    sidebarMenuOutput("menu")
  ),
  dashboardBody(
        tabItems(
          tabItem(tabName = "m1", p("Menu content 1") ),
          tabItem(tabName = "m2", p("Menu content 2") )
    )
   )
)
server <- function(input, output) {
  output$menu <- renderMenu({
    sidebarMenu(
      menuItem("Menu item1", tabName="m1", icon = icon("calendar")),
      menuItem("Menu item2", tabName="m2", icon = icon("database"),selected = TRUE)
    )
  })
}
shinyApp(ui, server)

Edit : Indentation problem that occurs with Romain's anwser hsh

Community
  • 1
  • 1
Servet
  • 267
  • 3
  • 12
  • Do you need to use `dropdownMenuOutput("menu")`? [Source](https://rstudio.github.io/shinydashboard/structure.html) Also if you check the source, that function is called within `dashboardHeader()`, not `dashboardSidebar()` – Adam Birenbaum Apr 20 '16 at 13:04
  • Well, no, I don't use it, because I don't want dropdown menus. Why? – Servet Apr 20 '16 at 13:07
  • Oh wow oops. Sorry, it's early. – Adam Birenbaum Apr 20 '16 at 13:09
  • 1
    If you take a look at [here](https://rstudio.github.io/shinydashboard/structure.html#dynamic-content-1), the dynamic sidebar menu items are added inside dashboardSidebar() – Servet Apr 20 '16 at 13:11

2 Answers2

8

You have effectively to use updateTabItems(). To do so you have to set up an id for the sidebarMenu and update the corresponding menuItem or menuSubItem.

For your specific case you should do something like this:

library(shiny)
library(shinydashboard)
ui <- dashboardPage(
  dashboardHeader(title = "Dynamic sidebar"),
  dashboardSidebar(
    sidebarMenu(id="tabs",
    sidebarMenuOutput("menu")
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "m1", p("Menu content 1") ),
      tabItem(tabName = "m2", p("Menu content 2") )
    )
  )
)
server <- function(input, output,session) {

  output$menu <- renderMenu({
    sidebarMenu(
           menuItem("Menu item1", tabName="m1", icon = icon("calendar")),
           menuItem("Menu item2", tabName="m2", icon = icon("database"))
           )
  })
  isolate({updateTabItems(session, "tabs", "m2")})
}
shinyApp(ui, server)

Edited version to remove the indentation problem

Romain
  • 440
  • 4
  • 17
  • Funny, the idea of using dashboardSidebar() twice, both in server and ui code.... Never thought of it. It works, but there is a strange indentation problem (posted screenshot at the end of my initial post). Does it occur to you too? Does not look good like this. – Servet Apr 30 '16 at 20:01
  • Found a solution. I edited my answer. The solution was to define the id of the Sidebar in the UI. Hope it helps. – Romain May 02 '16 at 07:03
  • It definitely helps. This is the solution I was looking for. Thank you. – Servet May 02 '16 at 12:14
  • @Romain, I have a question. what if I have two render menu items. I have been trying to find a solution to that. Let me know if you have any suggestion. – Dinesh.hmn Aug 01 '17 at 03:33
  • Hi, can you please provide some reproductible code so I can see what you mean by "two render menu items". Is it two conditionnal item? – Romain Aug 02 '17 at 05:29
  • @Dinesh.hmn I think I get what you are saying, so let me try answering. You can only render one menu item at once, otherwise content for both menus will be rendered one after another, which defeat the purpose of a menu. I had this confusion before, and eventually figured out a way to render each menu content dynamically. See my own [SO post](https://stackoverflow.com/questions/46854589/shiny-dashboard-render-multiple-menu-items-and-output-dynamic-content-to-each). – Boxuan May 15 '18 at 17:23
0

Why not using an observer which is called only once at app init

observe({ # called only once at app init
  updateTabItems(session, "tabs", "m2")
})
sigbert
  • 77
  • 5