Andrew Scotchmer
Andrew Scotchmer

Reputation: 313

Preload all tabs when shiny app loads

Below is a simple reproducible app. I have two tabs. Tab 1 displays a chart while Tab 2 displays a chart and table.

I have also a download button in the side bar and an Rmd document.

The question is, the resulting html page I want to download fails unless I select Tab 2. When I select Tab 2 the download works fine even if I go back to Tab 1 before downloading. Obviously this is due in part to the reactive element on Tab 2.

However, I want the download to work whether or not I visit Tab 2. In other words when the app loads I can just click the download button and the resulting html page will contain the charts and the table from both tabs.

Is there a way to preload Tab 2? As you can see, I have tried the outputOptions function with suspendWhenHidden = FALSE but it doesn't seen to work.

Any help please?

Shiny:

library(shiny)
library(rmarkdown)


data(mtcars)


ui <- fluidPage(
  titlePanel("Preload Plots"),

  sidebarPanel(
    uiOutput("down")
  ),


  mainPanel(
    fluidRow(
      tabsetPanel(
        tabPanel("Panel 1",
                 plotOutput("plot1")
                 ),
        tabPanel("Panel 2",
                 uiOutput("selectList"),
                 plotOutput("plot2"),
                 tableOutput("tbl")
                 )
      )
    )
  )
)


server <- function(input, output){


  output$plot1 <- renderPlot({
    barplot(mtcars$cyl)
    })


  output$selectList <- renderUI({
    selectInput("selectionBox", "Select Cyl Size", unique(mtcars$cyl), selected = 4)
  })

  cylFun <- reactive(
     mtcars[mtcars$cyl == input$selectionBox, c("mpg", "wt")]
  )

  output$plot2 <- renderPlot({
    plot(cylFun())
    })

  outputOptions(output, "plot2", suspendWhenHidden = FALSE)


  output$tbl <- renderTable(
    table(cylFun())
  )

  outputOptions(output, "tbl", suspendWhenHidden = FALSE)

  output$down <- renderUI({
    downloadButton("downloadPlots", "Download Plots")
  })

  output$downloadPlots <- downloadHandler(
    filename = "plots.html",

    content = function(file){
      params = list(p2 = cylFun())
      render("plots.Rmd", html_document(), output_file = file)
    }
  )

}


shinyApp(ui, server

Rmarkdown:

---
title: "plots"
output: html_document
---

```{r, echo = FALSE}

barplot(mtcars$cyl)

```

```{r, echo = FALSE}

plot(params$p2)
knitr::kable(params$p2)

```

Thanks
Andrew

Upvotes: 2

Views: 2451

Answers (2)

Rahul Mishra
Rahul Mishra

Reputation: 230

An easily available hack to load all tabs using your downloadButton renderUI. Using req keyword as below. This will load all the outputs and all tabs will be loaded and then appear.

 output$down <- renderUI({
    req(plot1,selectList,plot2,tbl)
    downloadButton("downloadPlots", "Download Plots")
  })

Enjoy!

Upvotes: 0

Christoph Wolk
Christoph Wolk

Reputation: 1758

You have the right idea, suspendWhenHidden seems to be the key. The problem is that the Rmd rendering needs cylFun to have a value, and cylFun depends on the selectionBox input value you create with renderUI. You have the suspendWhenHidden option for the plot and table, but these cannot be calculated without selectionBox, and the markdown works without them.

So just add

  outputOptions(output, "selectList", suspendWhenHidden = FALSE)

and it should work. You can also remove the outputOptions for the table and plot on tab 2.

Upvotes: 1

Related Questions