简体   繁体   中英

Create conditional menuitems and menuSubItems in Shiny

I found how to create dynamically a menu at: http://rstudio.github.io/shinydashboard/structure.html#dynamic-content-1 . But, I cannot figure out how to get what I would need.

With the code given in the link above and if statements, I was able to create or not a WHOLE menu relevant to other inputs in my app. But now what I am looking for is flexibility on each items/subitems. For instance, for a default menu like this:

Analyses

  1. Analysis 1
  2. Analysis 2
  3. Analysis 3

I would like to find a way to only show Analysis 1 and 3 if the files needed for analysis 2 are is not present on the server.

So dependant on my app inputs (drop down menus) and other parameters, I would want to be able to change the menu itself. Is that possible?

So far I have tried to find a way to dynamically concatenate menuItems/subMenuItems but no luck.

I have also tried to cheat and generate strings with the right html tags. But this do not seem to work either. Not sure why yet.

Following up the first comments/answers to my question. I am putting below a minimal example of what I have tried. I appreciate this is an ugly way of doing it and it does not work (no menu appearing). It is all based on Pascallv minimal example in the first answer:

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
 dashboardHeader(title = "Dynamic sidebar"),

  dashboardSidebar(
    sidebarMenuOutput("menu")
  ),

  dashboardBody(selectInput(inputId = "SelectFolder", label = "Select my 
  analysis folder", choices = 
                          c(".", "..", "../.."))) 
)



server <- function(input, output) {

  # whenever input$hide_tab changes through user input, output$menu adapts
  observeEvent(input$SelectFolder,{

    content<-list.files(input$SelectFolder)
    menu <- '<ul id="mymenu" class="sidebar-menu">'
    menu <-paste0(menu,menuItem("analysis 1", tabName = "a1", icon = icon("list-ul")))
   if("app.R" %in% content){
      menu <-paste0(menu,menuItem("analysis 2", tabName = "a2", icon = icon("bar-chart")))
    }
    menu <-paste0(menu,"</ul>") # end of the whole menu
    output$menu <- renderMenu(menu)
  } )  
}


shinyApp(ui, server)

The reason why Pascallv solution does not work for me is because I have a lot of different cases (the menu can be big) and I cannot cover all possible combinations of analyses being present in my folders or not by creating 50+ different menus. Does it make more sense now please?

You could for example use observeEvent() in the server code and by that make the menu react to any change in input you like.

I do not know what exactly you want to do, because you did not provide a minimal example of what you did so far. Yet I am sure you can transfer this example to your code:

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
   dashboardHeader(title = "Dynamic sidebar"),

   dashboardSidebar(
     sidebarMenuOutput("menu")
   ),

  dashboardBody(selectInput(inputId = "hide_tab", label = "Hide a tab?", choices = 
                c("1", "2", "3"))) 
)



server <- function(input, output) {

    # whenever input$hide_tab changes through user input, output$menu adapts
    observeEvent(input$hide_tab,{

    if(input$hide_tab== "1"){
      output$menu <- renderMenu({
      sidebarMenu(
      menuItem("Menu item", menuSubItem("analysis 2"), menuSubItem("analysis 3")))}) 
    }

    if(input$hide_tab== "2"){
        output$menu <- renderMenu({
        sidebarMenu(
        menuItem("Menu item", menuSubItem("analysis 1"), menuSubItem("analysis 
3")))})
    }

    if(input$hide_tab== "3"){
        output$menu <- renderMenu({
        sidebarMenu(
        menuItem("Menu item", menuSubItem("analysis 1"), menuSubItem("analysis 
2")))})
    }

  })
}


shinyApp(ui, server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM