79620361

Date: 2025-05-13 20:18:22
Score: 1
Natty:
Report link

Apparently "shinyjs::hidden()" updates css to "display:none;" which makes the button unclickable. After a small modification, it started working. Thanks @Mikko and @smartse for your input. Below is the working example with single click download using ExtendedTask feature:

library(shiny)
library(bslib)
library(future)
library(promises)
future::plan(multisession)

ui <- fluidPage(
  shinyjs::useShinyjs(),
  titlePanel("Cars Data"),
  textOutput("time"),
  bslib::input_task_button("export", "Export", icon = icon("file-export")),
  downloadButton("download", "Download", style = "position: absolute; left: -9999px; top: -9999px;"),
)

server <- function(input, output, session) {
  # Just to prove UI is not blocked.
  output$time <- renderText({
    invalidateLater(1000)
    format(Sys.time())
  })
  
  # Task that prepares a file with the data for download.  
  export_task <- ExtendedTask$new(function(file) {
    promises::future_promise({
      data <- mtcars
      Sys.sleep(2)
      write.csv(data, file)
      file
    })
  }) |> bslib::bind_task_button("export")
  
  # Set up a reusable file for this session's download data.
  download_content_path <- tempfile("download_content")
  
  observeEvent(input$export, export_task$invoke(download_content_path))
  
  # Show download button only when file is ready.
  observe({
    if (export_task$status() == "success") {
      showNotification("Your download is ready.")
      shinyjs::click("download")
    }
  })
  
  # Handle download with file prepared by task.  
  output$download <- downloadHandler(
    filename = function() {
      paste0("Data-", Sys.time(), ".csv")
    },
    content = function(file) {
      file.rename(export_task$result(), file)
    }
  )
}

shinyApp(ui = ui, server = server)
Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Mikko
  • User mentioned (0): @smartse
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Deep