Brilliant app: disable downloadbutton

My brilliant application creates some files that the user can download. I put downloadbutton in ui for this purpose. However, when the page starts up and before performing any calculations, there is nothing to load. I want the user not to load blank pages.

For this, I'm going to disable downloadButton before exiting. But I do not know how to do this. I found ways to disable ActionButton (e.g. ShinyBS package and other JS codes), but nothing for downloadButton.

I am currently using validate () to throw errors if the output is not ready. However, when you click the downloadButton button, a new blank web page opens with an error message that is ugly.

let me know what you think.

This is my ui code

downloadButton('download', 'Download Lasso component matrix')), 

and this is my server code:

  output$download_matrix <- downloadHandler( filename = function() { validate( need(is.null(outputData())==FALSE, "No data to download yet") ) paste('combined_model_matrix', '.txt', sep='') }, content = function(file) { write.csv(outputData()$combinedAdjMtr, file) }) 
+8
javascript r shiny shinyjs
source share
2 answers

Based on your comment:

Yes, data processing depends on user input. The user will upload some files and click the "Activation" button to begin processing. The download button is in a set of tabs.

Let's say the action button is called input$start_proc .

In server.R:

 shinyServer(function(input, output, session) { #... other code observe({ if (input$start_proc > 0) { # crunch data... # when data is ready: session$sendCustomMessage("download_ready", list(...)) # you can put extra information you want to send to the client # in the ... part. } }) #... other code }) 

Then in ui.R you can write javascript for the custom message event handler.


Full example:

server.R

 library(shiny) fakeDataProcessing <- function(duration) { # does nothing but sleep for "duration" seconds while # pretending some background task is going on... Sys.sleep(duration) } shinyServer(function(input, output, session) { observe({ if (input$start_proc > 0) { fakeDataProcessing(5) # notify the browser that the data is ready to download session$sendCustomMessage("download_ready", list(fileSize=floor(runif(1) * 10000))) } }) output$data_file <- downloadHandler( filename = function() { paste('data-', Sys.Date(), '.csv', sep='') }, content = function(file) { write.csv(data.frame(x=runif(5), y=rnorm(5)), file) } ) }) 

ui.R

 library(shiny) shinyUI(fluidPage( singleton(tags$head(HTML( ' <script type="text/javascript"> $(document).ready(function() { // disable download at startup. data_file is the id of the downloadButton $("#data_file").attr("disabled", "true").attr("onclick", "return false;"); Shiny.addCustomMessageHandler("download_ready", function(message) { $("#data_file").removeAttr("disabled").removeAttr("onclick").html( "<i class=\\"fa fa-download\\"></i>Download (file size: " + message.fileSize + ")"); }); }) </script> ' ))), tabsetPanel( tabPanel('Data download example', actionButton("start_proc", h5("Click to start processing data")), hr(), downloadButton("data_file"), helpText("Download will be available once the processing is completed.") ) ) )) 

In this example, the data processing is faked, waiting for 5 seconds. Then the download button will be ready. I also added some “fake” fileSize information to the fileSize to demonstrate how you can send additional information to the user.

Note that since Shiny implements actionButton as an <a> tag instead of a <button> and associates a click event with it. Therefore, in order to completely disable it, in addition to adding the disabled attribute, so that it seems to be disabled, you also need to override its click event by adding the onclick built-in attribute. Otherwise, the user may accidentally click the download button (apparently disabled) and start the download.

+9
source share

Just add another answer that works similar to the Xin answer, but using a package ( coming from scratch ) that initially supports turning buttons on / off, rather than having to deal with dirty JavaScript yourself. Using this package, you can simply call disable("download") or enable("download") .

Here is a complete example of replication of the Xin response, but with this package

 library(shiny) library(shinyjs) runApp(shinyApp( ui = fluidPage( # need to make a call to useShinyjs() in order to use its functions in server shinyjs::useShinyjs(), actionButton("start_proc", "Click to start processing data"), downloadButton("data_file") ), server = function(input, output) { observe({ if (input$start_proc > 0) { Sys.sleep(1) # enable the download button shinyjs::enable("data_file") # change the html of the download button shinyjs::html("data_file", sprintf("<i class='fa fa-download'></i> Download (file size: %s)", round(runif(1, 1, 10000)) ) ) } }) output$data_file <- downloadHandler( filename = function() { paste('data-', Sys.Date(), '.csv', sep='') }, content = function(file) { write.csv(data.frame(x=runif(5), y=rnorm(5)), file) } ) # disable the downdload button on page load shinyjs::disable("data_file") } )) 
+16
source share

All Articles