Search code examples
rshinyui-automationflexdashboardaction-button

create buttons dynamically using Shiny and/or flexdashboard


The task is to generate an app layout based on the folder structure on my server. There are folders and in each of them there are several RMarkdown files. I want a Shiny/Flexdash board app that will automatically take the folder structure with all the files in the folders, create a page for each folder and add an action button for each item on the respective site linked to the RMD file. So when you click the button, the file will open. (Shiny-App with folder structure)

Since the folder structure and the files inside are constantly changing and it would be too time consuming to edit the Shiny/Flexdashboard app itself, I would like to automate the creation of both the buttons and the pages.

Automatic page generation based on folder structure is not a problem (see code example), but automatic creation of action buttons is quite difficult. I've searched a variety of ways but haven't found anything that works for me.

Maybe someone has tried the same thing in the past and can help me.

for (i in 1:length(all_files$folder %>% unique()))
{
  df <- all_files$folder %>% unique() %>% "["(i)
  cat("\n")
  cat("# ", df, "\n")
}

I tried different ways liked add actionButtons() in for-loops, for-loops packed into reactive, paste the actionButton() code to the cat() function etc. Also Google can't help me


Solution

  • I've tried a lot over the past few weeks and finally found a solution that works for me. Maybe this will help you.

    I designed a Shiny app running in Flexdashboard. I'm using the Shiny function insertTab() in the Shiny app's server function (see attached code below). You can use this function to insert tabs anywhere in a NavbarPage. In order to be able to use this function, at least one tab must be predefined in the user interface (see UI function). I added an overview of the tabs for myself. In the server function, I run a for loop to generate a tab for each folder. For the tab, I use lapply() to create a list of buttons for each file in the folder. The list contains an HTML paragraph with the button and a line break to place the buttons one below the other. If you don't want this, just delete br().

    A Sample of the data structure when reading the folders and the files in the folders can be seen below.

    FOLDER FILE
    folder 1 file 1
    folder 1 file 2
    folder 2 file 1
    folder 3 file 1
    ui <- navbarPage("PAGENAME", id = "tabs", tabPanel("Overview",))
    
    server <- function(input, output)
    {
     FOLDERNAMES <- DATA$FOLDER %>% unique() 
      for (j in FOLDERNAMES) 
        {
        apps <- DATA %>% filter(FOLDER == j) %>% pull(FILE)
        insertTab(
        inputId = "tabs", target = "Overview", 
            tab = tabPanel(j,
                    mainPanel(
                                lapply(1:length(apps),function(i)
                                        {
                                            p(actionButton(inputId = apps[i], label = apps[i]), br())
                                        }
                                      )
                             )
                          )
                 )
         }
    }
    shinyApp(ui, server)
    

    I hope this helps you guys.