Aqqi
Aqqi

Reputation: 125

Not able to place conditional check on download button

I want to place a conditional check on a download button btnDownload. If a particular dataframe recData$dfData() has no data, then on clicking the download button, it must show an alert: "A report can't be download due no data present."

observeEvent(input$btnDownload, {

  if (nrow(recData$dfData()) != 0) {
    output$btnDownload <- downloadHandler(
      "rpa foundary.docx",
      content = function(file) {
        trycatch(
          expr = {

            if (file.exists("rpa foundary.docx")) {
              file.remove("rpa foundary.docx")
            }

            mydoc <- CreateReportDoc(recData$dfData(), recData$dfProjectWeeklyDtls())

            print(mydoc, file)
            print(mydoc, file, target = "rpa foundary.docx")
            shinyalert(
              type = "success",
              title = "download complete!", 
              text = paste0("report downloaded successfully")
            )
          }, error = function(e) {
            logerror(e, fxname = "btnDownload", app = "server.r")
          }, warning = function(w){
            logwarning(w, fxname = "btnDownload", app = "server.r")
          }
        )}## downloader   
      )} else {
        shinyalert(
          type = "error", title = "report cannot be downloaded!",
          text = paste0("no data available to display")
        )
      }
    })

I was expecting only alert when recData$dfData() has no data. But i am getting ![c:Libraries\Pictures\dwnld.png] html document download.

Upvotes: 2

Views: 1282

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

As suggested by @DSGym, I would rather disable the button when the data is not available. We can also add a tooltip to provide info to the user.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  br(),br(),
  div(id="dwnbutton", 
    downloadButton("downloadData", "Download", disabled = "disabled")
  ),
  br(), br(),
  actionButton("go", "Go")
)

server <- function(input, output) {
  # Our dataset - empty at initialisation
  data <- reactiveVal(data.frame())

  observeEvent(input[["go"]], {
    data(mtcars)
  })

  observeEvent(data(), {
    if(nrow(data()) > 0){
      enable("downloadData")
      runjs("$('#dwnbutton').removeAttr('title');")
    }else{
      disable("downloadData")
      runjs("$('#dwnbutton').attr('title', 'Data not available');")
    }
  })

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(data(), file)
    }
  )
}

shinyApp(ui, server)

enter image description here


If you really want an alert, here is a way.

library(shiny)
library(shinyjs)
library(shinyWidgets)

ui <- fluidPage(
  useShinyjs(),
  br(),br(),
  div(id="dwnbutton", 
      downloadButton("downloadData", "Download", 
                     onclick = "Shiny.setInputValue('dwnClicked', true, {priority:'event'});")
  ),
  br(), br(),
  actionButton("go", "Go")
)

server <- function(input, output, session) {
  # Our dataset - empty at initialisation
  data <- reactiveVal(data.frame())

  observeEvent(input[["go"]], {
    data(mtcars)
  })

  observeEvent(data(), {
    if(nrow(data()) > 0){
      runjs("$('#dwnbutton').off('click.x');")
    }else{
      runjs("$('#dwnbutton').on('click.x', function(e){e.preventDefault();});")
    }
  })

  observeEvent(input[["dwnClicked"]], {
    if(nrow(data()) == 0){
      sendSweetAlert(
        session = session,
        title = "No data !",
        text = "No data available",
        type = "error"
      )
    }
  })

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(data(), file)
    }
  )
}

shinyApp(ui, server)

enter image description here

But at least I would add a style to the button to show that the data is not available:

  observeEvent(data(), {
    if(nrow(data()) > 0){
      runjs("$('#dwnbutton').off('click.x');")
      runjs("$('#downloadData').removeClass('btn-danger');")
    }else{
      runjs("$('#dwnbutton').on('click.x', function(e){e.preventDefault();});")
      runjs("$('#downloadData').addClass('btn-danger');")
    }
  })

enter image description here

Upvotes: 6

Related Questions