Search code examples
rshinyshinydashboard

Generate a shiny dashboard sidebarmenu that contains both static and dynamic tabs based on file input


I am reading in a csv file and then creating a shiny dashboard with some tabs on the sidebar where some are static and others will change based upon the input file. For example, a simplified version of the data file might look like this:

Name Extension Series
John 8648 Engineer
Jill 4783 Analyst
Dave 3749 Sales
Mary 3468 Engineer

I will not know in advance how long the csv input file is, or how many different job series might be contained in the "Series" column. On my dashboard, I would like to have tabs on the sidebar such as these:

  1. General Info - this will contain info that is relevant to all employees of the company
  2. Next I would like to have tabs that pertain to each of the different employee types (Series). I per unique Series value.
  3. Then there will be other static tabs. Currently I have a "Detailed Analysis" tab after the dynamic tabs.

So, for this example input file, I would have tabs that looked like this on the side bar:

  • General Info
  • Analyst
  • Engineer
  • Sales
  • Detailed Analysis

I have changed the data for simplicity and also because the actual data is sensitive. I think I am close to getting what I want, but it only works if there is just one type of employee (Series column). I get an error if there is more than one Series type which says:

Error: Text to be written must be a length-one character vector

Also, if there is only one Series type, I get the correct tab name on the side bar panel, but it doesn't do anything if I click on it. I don't have a ton of experience with R or Shiny, I only work on it when I have time, so I am sure I am doing something stupid. I have looked at a lot of other entries on Stack Overflow, but I don't think there are any answers for my exact situation and I am not knowledgeable enough yet to really run with answers to similar, but different issues.

Here is the latest code I am using

After reading in the csv file, I determine the different unique Series values that I want to create my tabs for:

menu_list <- unique(employee_df$Series)

Here is the relevant part of my UI section:

  ui <- dashboardPage(
    dashboardHeader(title = "Employee Dashboard"),
    dashboardSidebar( 
      sidebarMenu(id = "sidebar_menu",
        menuItem("General Info", tabName = "general", icon = icon("dashboard")),
        menuItemOutput("dynamic_menu"),
        menuItem("Detailed Analysis", tabName = "analysis", icon = icon("dashboard"))
      )

And here is the relevant part of my server section:

  server <- function(input, output, session) {
    output$dynamic_menu <- renderMenu({
      menuItem(menu_list, icon = icon("dashboard"))    
    })

Solution

  • Try this

    employee_df <- read.table(text = 
                                "Name   Extension   Series
    John    8648    Engineer
    Jill    4783    Analyst
    Dave    3749    Sales
    Mary    3468    Engineer
    John2   8641    Engineer
    Jill2   4781    Analyst
    Dave2   3741    Sales
    Mary2   3461    Engineer", header=T)
    
    ui <- dashboardPage(
      dashboardHeader(title = "Employee Dashboard"),
      dashboardSidebar( 
        sidebarMenu(id = "sidebar_menu",  
                    sidebarMenuOutput("dynamic_menu")
        )
      ),
      dashboardBody()
    )
    
    server <- function(input, output, session) {
      
      menu_list <- unique(employee_df$Series)
      
      output$dynamic_menu <- renderMenu({
        menus <- list()
        lapply(menu_list, function(tab){ 
          mytab <- sprintf("%s",tab)
          print(mytab)
          menus <<- list(menus,menuItem(mytab, tabName=mytab, icon = icon("dashboard")))
        })
    
        mymenu_list <- list(
        
                    menuItem("General Info", tabName = "general", icon = icon("dashboard")),
                    menus,
                    menuItem("Detailed Analysis", tabName = "analysis", icon = icon("dashboard"))
        
        )
        sidebarMenu(.list = mymenu_list)
          
      })
    }
    
    shinyApp(ui, server)