I want users to download a file from my shiny app. However, if they don't input correctly certain parameters inside a textInput()
widget (e.g. a correct e-mail), I want to stop the download and display a notification (through the use of the functionalities of shinyjs
for example).
However, if I put an if
statement inside the content
argument of downloadHandler()
, if the condition is not met, the button fires the download anyway, but the result is just an empty HTML file reporting a 404 error. I've slightly modified the Shiny example showing the use of downloadHandler()
to report this behaviour:
library(shiny)
library(tidyverse)
# UI
ui <- fluidPage(
textInput(input = "text",
label = "Write 'download' to download the correct file"),
br(),
downloadButton(outputId = "downloadData",
label = "Download")
)
# SERVER
server <- function(input, output) {
data <- mtcars
output$downloadData <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep = "")
},
content = function(file) {
if (input$text == "download") {
write.csv(x = data,
file = file)
}
}
)
}
shinyApp(ui, server)
Two scenarios will possibly solve the problem:
a) avoid the download of the HTML file reporting the error;
b) display a notification that does not constantly update each time I write something wrong in the text input until the right text is added.
Thanks in advance for your help!
CodePudding user response:
To expand on my comment above:
library(shiny)
library(tidyverse)
library(shinyjs)
# UI
ui <- fluidPage(
useShinyjs(),
textInput(input = "text",
label = "Write 'download' to download the correct file"),
br(),
downloadButton(outputId = "downloadData", label = "Download")
)
# SERVER
server <- function(input, output) {
data <- mtcars
observeEvent(input$text, {
if (input$text == "download") {
enable("downloadData")
} else {
disable("downloadData")
}
})
output$downloadData <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep = "")
},
content = function(file) {
write.csv(x = data, file = file)
}
)
}
shinyApp(ui, server)
Giving
and
[Note the change in font colour on the Download widget.]
Edit
In response to OP's request in the comments below, to use the shinyFeedback package...
- Load the package and add the necessary call to the UI definition:
...
library(shinyFeedback)
# UI
ui <- fluidPage(
useShinyjs(),
useShinyFeedback(), ...
- Modify the
observeEvent
that watches thetextInput
:
observeEvent(input$text, {
if (input$text == "download") {
hideFeedback("text")
enable("downloadData")
showFeedbackSuccess("text", "Ready to download")
} else {
disable("downloadData")
showFeedbackDanger("text", "Please enter the password")
}
})
This gives
and