rshinyaccordionlapplyshinydashboardplus

Can you add shinydashboardplus accordion items using lapply or a loop?


I'm trying to create an accordion in a shiny app using shinydashboardplus accordion function and, since it's very repetitive and all the info for the accordion comes from a datable, ideally I'd like to use a lapply function or for loop. I'm not sure whether this is possible though. Here's my code so far.

library("shiny")
library(shinydashboardPlus)

data(iris)

# UI ----
ui <- fluidPage(
  
  # App title ----
  titlePanel("Hello Shiny!"),
  
  # Sidebar layout  ----
  sidebarLayout(
    
    # Sidebar panel ----
    sidebarPanel(
      
      p("Some text")
      
    ),
    
    # Main panel ----
    mainPanel(
      
      # Output: accordion ----
      accordion(
        
        id = "id-accordion",
        
            #for (i in 1:3){
            #  accordionItem( #G11
            #    title = unique(ocup$nom2d[i]),
            #    tableOutput(paste0("table",i))
            #  )
            #  
            #}
        
            accordionItem( #G11
              title = unique(iris$Species)[1],
              tableOutput("table1")
            ), #G11 fin
            accordionItem( #G12
              title = unique(iris$Species)[2],
              tableOutput("table2")
            ), #G12
            accordionItem( #G13
              title = unique(iris$Species)[3],
              tableOutput("table3")
            )  #G13
        
        
      ) 
      
    )
  )
)


server <- function(input, output) {
 
  lapply(1:3, function(i){
    outputId <- paste0("table", i)
    output[[outputId]] <- renderTable({iris %>% filter(Species == unique(iris$Species)[i]) %>% select(Sepal.Length, Sepal.Width)})
  })
  
}


shinyApp(ui, server)

I've also considered using reactable instead of an accordion but I can't get it to look nicely (see question Custom JS aggregation function reactable groups pull data from table )

Thank you in advance for all your help.


Solution

  • You can use a combination of do.call and lapply to create the accordionItem's programmatically:

    library(shiny)
    library(shinydashboardPlus)
    
    data(iris)
    
    ui <- fluidPage(
      titlePanel("Hello Shiny!"),
      sidebarLayout(
        sidebarPanel(
          p("Some text")
        ),
        mainPanel(
          do.call(accordion, c(list(id = "id-accordion"), lapply(seq_along(unique(iris$Species)), function(i){
            accordionItem(
              title = unique(iris$Species)[i],
              tableOutput(paste0("table", i))
            )
          })))
        )
      )
    )
    
    server <- function(input, output) {
      lapply(1:3, function(i){
        outputId <- paste0("table", i)
        output[[outputId]] <- renderTable({iris %>% filter(Species == unique(iris$Species)[i]) %>% select(Sepal.Length, Sepal.Width)})
      })
    }
    
    shinyApp(ui, server)