updateDateInput based on another dateInput issue in shiny

Hello. I'm having an issue with dateInput and updateDateInput in shiny.

I have to update the "End Date" based on the date inserted in "Start Date". The strange thing to me is that if i use "Sys.Date() - 1" as minimum value in the start date input, the update works almost well (it just don't show de default value, even that i had specify it in the updateDateInput).

But when i use only "Sys.Date()" as minimum value in the Start Date input, the End Date input do not update and not even works (the calendar box do not open).

The updateDateInput will be working because the minimum value in "Start Date" input is set as Sys.Date() - 1. If i let just Sys.Date(), the updateDateInput do not work anymore.

Reprex:

library(shiny)


ui <- fluidPage(
   
   titlePanel("Doubt App"),
   
   sidebarLayout(
      sidebarPanel(
        dateInput("start_date",
                  label = HTML("Start Date","&nbsp",as.character(actionLink(inputId = "info2", 
                                                                                           label = "", 
                                                                                           icon = icon("info")))),
                  #min = Sys.Date()  # This do not work
                  min = Sys.Date()-1 # This work
                  , max = Sys.Date()+30,
                  format = "dd/mm/yy",
                  startview = 'day', weekstart = 1),

        dateInput("end_date",
                  label = HTML("End Date","&nbsp",as.character(actionLink(inputId = "info3",
                                                                                                        label = "",
                                                                                                        icon = icon("info")))),
                  format = "dd/mm/yy",
                  startview = 'day', weekstart = 1)
      ),
      
      mainPanel(
        tabPanel("Output", DT::dataTableOutput("mytable"))
      )
   )
)

server <- function(input, output,session) {
   
  observeEvent(input$start_date,{
    updateDateInput(session,"end_date",
                    value = Sys.Date()+120,
                    min = Sys.Date()+120,
                    max = Sys.Date()+210
    )
  })

   output$mytable <- DT::renderDataTable({DT::datatable(
     as.data.frame(cbind(format(input$start_date,"%d/%m/%Y"),
                         format(input$end_date,"%d/%m/%Y"))),
     options = list(pageLength = 200))})
}

shinyApp(ui = ui, server = server)

Hi @ac_mattos. Both Sys.Date() and Sys.Date()-1 are working for me.

1 Like

Hello @raytong,

Have any guess why this doesn't work for me? In what country are you running this code?

When i use only Sys.Date(), not even the mainPanel shows, look:

I confirm the behavior seen by @ac_mattos that using Sys.Date() does not work.

> sessionInfo()
R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

Random number generation:
 RNG:     Mersenne-Twister 
 Normal:  Inversion 
 Sample:  Rounding 
 
locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.4.0

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.3         later_1.0.0        compiler_3.6.2     pillar_1.4.3      
 [5] prettyunits_1.0.2  tools_3.6.2        digest_0.6.23      pkgbuild_1.0.6    
 [9] jsonlite_1.6       lifecycle_0.1.0    tibble_2.1.3       gtable_0.3.0      
[13] pkgconfig_2.0.3    rlang_0.4.2        cli_2.0.0          rstudioapi_0.10   
[17] crosstalk_1.0.0    yaml_2.2.0         parallel_3.6.2     loo_2.2.0         
[21] fastmap_1.0.1      gridExtra_2.3      dplyr_0.8.3        htmlwidgets_1.5.1 
[25] DT_0.11            stats4_3.6.2       grid_3.6.2         tidyselect_0.2.5  
[29] glue_1.3.1         inline_0.3.15      R6_2.4.1           processx_3.4.1    
[33] fansi_0.4.0        rstan_2.19.2       farver_2.0.1       ggplot2_3.2.1     
[37] callr_3.4.0        purrr_0.3.3        magrittr_1.5       promises_1.1.0    
[41] htmltools_0.4.0    scales_1.1.0       ps_1.3.0           StanHeaders_2.19.0
[45] matrixStats_0.55.0 assertthat_0.2.1   xtable_1.8-4       mime_0.8          
[49] colorspace_1.4-1   httpuv_1.5.2       labeling_0.3       lazyeval_0.2.2    
[53] munsell_0.5.0      crayon_1.3.4      
1 Like

@ac_mattos. Sorry. I misunderstand your question. It is really a strange behaviour. But it not the problem of input$start_date. It is due to the min value of input$end_date. You set the min value to Sys.Date() + 120. And the update seem use the Sys.Date() to update first and cause fail. The update of new value never process again. So if you remove the min value, the update will be okay. You can observe the print value of the input$end_date. I add a delay on another updateDateInput and it finally update to new value.
This should be a bug. You may report an issue on this.

library(shiny)
library(shinyjs)


ui <- fluidPage(
  
  titlePanel("Doubt App"),
  useShinyjs(),
  
  sidebarLayout(
    sidebarPanel(
      dateInput("start_date",
                label = HTML("Start Date","&nbsp",as.character(actionLink(inputId = "info2", 
                                                                          label = "", 
                                                                          icon = icon("info")))),
                #min = Sys.Date()  # This do not work
                min = Sys.Date()-1 # This work
                , max = Sys.Date()+30,
                format = "dd/mm/yy",
                startview = 'day', weekstart = 1),
      
      dateInput("end_date",
                label = HTML("End Date","&nbsp",as.character(actionLink(inputId = "info3",
                                                                        label = "",
                                                                        icon = icon("info")))),
                format = "dd/mm/yy",
                startview = 'day', weekstart = 1)
    ),
    
    mainPanel(
      tabPanel("Output", DT::dataTableOutput("mytable"))
    )
  )
)

server <- function(input, output,session) {
  
  observeEvent(input$start_date,{
    
    updateDateInput(session,"end_date",
                    value = Sys.Date() + 120,
                    min = Sys.Date() + 120
                    , max = Sys.Date()+210
    )
  })
  
  observeEvent(input$start_date,{
    
    delay(500,
          updateDateInput(session,"end_date",
                          value = Sys.Date() + 120
          ))

  })
  
  observe({
    print(input$end_date)
  })
  
  output$mytable <- DT::renderDataTable({DT::datatable(
    as.data.frame(cbind(format(input$start_date,"%d/%m/%Y"),
                        format(input$end_date,"%d/%m/%Y"))),
    options = list(pageLength = 200))})
}

shinyApp(ui = ui, server = server)
1 Like

Thank you @raytong!

Very clarify!

So, i'm not able to set minimum value when updating a dateInput? I really need the constrainst that "input$end_date - input$start_date > 120" and "input$end_date - input$start_date < 210" (in days).

How could i

@ac_mattos. It seems you can't do it as once. You can set the min and max first. And add delay to update the new value as follow. Remember to import shinyjs library and call useShinyjs() in ui.

  observeEvent(input$start_date,{
    
    updateDateInput(session,"end_date",
                    min = Sys.Date() + 120
                    , max = Sys.Date()+210
    )
    
    delay(500,
          updateDateInput(session,"end_date",
                          value = Sys.Date() + 120
          ))
  })
1 Like

@raytong, thank you very much!

This worked but i also had to remove the minimum value in the "start_date".

I would like to have start_dates only from the current date, but i can sleep at night with that.

Where can i report this bug?

@ac_mattos. You may go to shiny github to report the bug.

1 Like

Hi All,
really looks like a bug, I wonder if it goes all the way back to the javascript bootstap/Jquery?
Anyway, perhaps it would be helpful to give you an alternative.
Here is a demo of airdatepickerinput from shinyWidgets package

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
       dateInput("a_date",
                label = "a date",
                min = Sys.Date() , 
                value = Sys.Date(),
                max = Sys.Date()+30,
                format = "dd/mm/yy",
                startview = 'day'),
       
    shinyWidgets::airDatepickerInput(inputId = "b_date",
                                     label = "b date",
                                     value = Sys.Date(),
                                     minDate = Sys.Date(),
                                     maxDate = Sys.Date()+30,
                                    view = 'days',
                                    dateFormat = "dd/mm/yy")
)

server <- function(input, output,session) {}
shinyApp(ui = ui, server = server)

I have also another idea for you to consider.
As it seems the secondary date field should be entirely dependent on first field, it might be worth considering placing it in the original UI as generic uiOutput(), and providing a renderUI function for it where you drop in the UI (whether dateInput or airdatepickerinput) with its parameters set on the reactive property of your first date picker. (this would avoid 'update' type semantics)

1 Like

Hello @nirgrahamuk,

I had tried that second suggestion before post the issue here =/ but the issue stills.

I have another input in the main app that is build this way. But the "End_date" still don't "update".

I will take a look in your first suggestion that uses shinyWidgets.

Thank you!

@nirgrahamuk, using uiOutput with the airDatepickerInput in both start and end_date works very well! it solved both problems of update and show the default value!

I will keep that in mind next time i work with date inputs!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.