I have a dropdown with two date presets and one "Custom" preset.
The "custom" preset should enable the user to use the date picker input to select a custom date range. If any other preset is selected, the date picker input should be disabled.
I start by disabling the element with shinyjs::disabled() as suggested here. Then I run shinyjs::disable() or shinyjs::enable(), depending on what preset is selected in the dropdown.
This is working as intended if I use disable/enable on a button, but for some reason the same does not work for the shinyWidget. It remains disabled when I select "Custom", even though shinyjs::enable() is triggered.
What am I missing?
Example:
library(shiny)
library(shinyWidgets)
library(shinyjs)
ui <- fluidPage(
shinyjs::useShinyjs(),
## pick a date preset
shinyWidgets::pickerInput(
inputId = "date_preset",
choices = c("Preset 1", "Preset 2", "Custom"),
selected = "Preset 1"
),
## custom date picker widget
uiOutput("ui_date_calendar"),
## test button
uiOutput("ui_testbutton"),
)
server <- function(input, output, session) {
# get date ranges for presets
date_range <- reactive({
shinyjs::disable("ui_date_calendar") # working
shinyjs::disable("ui_testbutton") # working
if (input$date_preset == "Custom"){
shinyjs::enable("ui_date_calendar") #NOT working
shinyjs::enable("ui_testbutton") #working
return(NULL)
}
if (input$date_preset == "Preset 1"){
return(c("2024-01-01", "2024-02-01"))
}
if (input$date_preset == "Preset 2"){
return(c("2024-02-01", "2024-03-01"))
}
})
# generate date picker UI
output$ui_date_calendar <- renderUI(
shinyjs::disabled(shinyWidgets::airDatepickerInput(
inputId = "date_picker",
value = date_range(),
range = TRUE,
placeholder = "Click to pick a date range"
))
)
# generate button UI
output$ui_testbutton <- renderUI(
shinyjs::disabled(actionButton("testbutton", "TEST"))
)
}
shinyApp(ui = ui, server = server)
I didn't experiment, but it looks strange to me to execute
shinyjs::disable/enableon theuiOutput; I would rather execute it on the widget contained in theuiOutput, e.g.shinyjs::enable("testbutton")instead ofshinyjs::enable("ui_testbutton").Now there's a problem here:
This
renderUIalways renders a disabled date picker. So, if you enable it but ifdate_range()changes, it is re-rendered in the disabled state. A solution to initially disable it is:Finally here is an app in which everything works as expected: