rshinyshiny-reactivityshinyjs

How to trigger events right before and after taking a Shiny screenshot?


I am trying to hide/show dedicated elements in my shiny app right before/after taking a screenshot with the shinyscreenshot package. I can't figure out the proper way to achieve this. I have tried with some invalidateLater but it results in the same error. What could be the clean way to achieve this (hide id = "options_results" and show "flag_options")? Here is an example:

library(shiny)

ui <- fluidPage(
  shinyjs::useShinyjs(),
      shinyjs::hidden(div(id = "flag_options", h2("This should be"), div(uiOutput("flag_reactive")))),
      
  div(id = "options_results", selectInput("choice_country", "Select Country", choices = c("US", "FR")),
          h2("This should not be in the screenshot")),
  
  actionButton("go_down", "Download")
)


server <- function(input, output) {
  
  
  output$flag_reactive <- renderUI({
    return(tags$img(src = paste0("https://cdn.rawgit.com/lipis/flag-icon-css/master/flags/4x3/", tolower(input$choice_country), ".svg", style = "width: 20%;")))
  })
  
  observeEvent(input$go_down, {
    shinyjs::hide("options_results", anim = FALSE)
    shinyjs::show("flag_options", anim = FALSE)
    shinyscreenshot::screenshot()
    shinyjs::show("options_results", anim = FALSE)
    shinyjs::hide("flag_options", anim = FALSE)
  })
}

# Return a Shiny app object
shinyApp(ui = ui, server = server)

Solution

  • This works for me. You had a typo / misplaced ) in your tags$img that was preventing the svg being displayed. I've also tidied up the js I used in the previous answer.

    enter image description here

    library(shiny)
    
    ui <- fluidPage(
      shinyjs::useShinyjs(),
      shinyjs::hidden(div(id = "flag_options", h2("This should be"), div(uiOutput("flag_reactive")))),
    
      div(id = "options_results", selectInput("choice_country", "Select Country", choices = c("US", "FR")),
          h2("This should not be in the screenshot")),
    
      actionButton("take_screenshot", "Download")
    )
    
    
    server <- function(input, output) {
    
      output$flag_reactive <- renderUI({
        return(tags$img(src = paste0("https://cdn.rawgit.com/lipis/flag-icon-css/master/flags/4x3/", tolower(input$choice_country), ".svg"), style = "width: 20%;"))
      })
    
      observeEvent(input$take_screenshot, {
        shinyjs::hide("options_results", anim = FALSE)
        shinyjs::show("flag_options", anim = FALSE)
        shinyjs::runjs("Shiny.setInputValue('take_screenshot2', new Date().getTime());")
      })
    
      observeEvent(input$take_screenshot2, {
        shinyscreenshot::screenshot()
        shinyjs::runjs("Shiny.setInputValue('take_screenshot3', new Date().getTime());")
      })
    
      observeEvent(input$take_screenshot3, {
        shinyjs::show("options_results", anim = FALSE)
        shinyjs::hide("flag_options", anim = FALSE)
      })
    
    }
    
    # Return a Shiny app object
    shinyApp(ui = ui, server = server)