Reputation: 5232
I want to change downloadButton label dynamically (in response to save_format
) and I would like for downloadButton to be disabled at first. I've tried to follow advice given in https://community.rstudio.com/t/renderui-to-create-an-input-thats-pre-disabled/59382 but it seems it only blurs downloadButton but still I can click on it. Here is example:
library(shiny)
ui <- navbarPage(
title = "TEST",
tabPanel(
"EXAMPLE",
bootstrapPage(
absolutePanel(
uiOutput(outputId = "download_ui"),
selectInput(
inputId = "save_format",
label = NULL,
choices = c("format1", "format2"),
selected = "csv"
)
)
)
)
)
server <- function(input, output) {
output$download_ui <- renderUI({
downloadButton(
outputId = "download",
label = str_c("Download ", input$save_format),
disabled = ""
)
})
output$download <- downloadHandler(
filename = function() {
str_c("file-", Sys.Date(), ".", input$save_format)
},
content = function(file){
# some function for saving in correct format
}
)
}
shinyApp(ui = ui, server = server)
I've also tried with disable
from shinyjs
right after renderUI but it didn't work. Also didnt find any updateDownloadButton function. Is there any solution for this?
Upvotes: 0
Views: 242
Reputation: 84529
Certainly shinyjs::disable
didn't work because the download button was not rendered yet. Here is a way which avoids renderUI
, so that you can use disable
. It also runs some JS code with runjs
to change the label.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
downloadButton("downloadData", "Download"),
br(),
selectInput(
inputId = "save_format",
label = NULL,
choices = c("csv", "xlsx"),
selected = "csv"
)
)
server <- function(input, output) {
# Our dataset
data <- mtcars
output$downloadData <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(data, file)
}
)
disable("downloadData") # disable download button
observeEvent(input$save_format, { # change download button label
runjs(
sprintf("$('#downloadData').contents()[2].nodeValue = '\\rDownload %s\\r'",
input$save_format)
)
})
}
shinyApp(ui, server)
Upvotes: 2
Reputation: 12461
You can be a bit sneaky and allow the downloadHandler
set a reactive value and then respond to changes in the reactive value. This works for me:
library(shiny)
library(shinyjs)
ui <- navbarPage(
useShinyjs(),
title = "TEST",
tabPanel(
"EXAMPLE",
bootstrapPage(
absolutePanel(
uiOutput(outputId = "download_ui"),
selectInput(
inputId = "save_format",
label = NULL,
choices = c("format1", "format2"),
selected = "csv"
)
)
)
)
)
server <- function(input, output) {
v <- reactiveValues(
downloadDone=FALSE
)
output$download_ui <- renderUI({
downloadButton(
outputId = "download",
label = str_c("Download ", input$save_format)
)
})
observeEvent(v$downloadDone, {
if (v$downloadDone) disable("download")
else enable("download")
})
output$download <- downloadHandler(
filename = function() {
str_c("file-", Sys.Date(), ".", input$save_format)
},
content = function(file){
v$downloadDone <- TRUE
}
)
}
shinyApp(ui = ui, server = server)
Upvotes: 0