默认的updateDateInput无法正常工作

时间:2020-07-12 18:09:08

标签: r shiny

我有一个简单的应用程序,它使用动态UI元素updateDateInput,以确保用户只能选择指定年份中的日期。所选日期应始终默认为所选年份的第一天。

library(shiny)
library(tidyverse)
library(lubridate)

ui <- fluidPage(
  selectInput("year", "Select Year:",
              choices = 2010:2020, selected = 2015),
  dateInput("date", "Select Date:", value = NULL)
)

server <- function(input, output, session) {
  observeEvent(input$year, 
               updateDateInput(session, "date", 
                               min = ymd(paste(input$year, "01-01", sep = "-")),
                               max = ymd(paste(input$year, "12-31", sep = "-")),
                               value = ymd(paste(input$year, "01-01", sep = "-"))))
}

shinyApp(ui, server)

向后移动所选年份(例如2015年至2014年)时,所选日期会自动更新到该月的第一天。但是,当用户将日期从2015年向前移动到2016年时,所选日期默认为null,并且用户需要手动搜索以获取当前年份日期。

有人可以帮我弄清楚为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

这是一个令人讨厌的问题,这使我花了很长时间才找到发生在我身上的问题。问题在于updateDateInput似乎进行了不是 atomic 的更改。也就是说,它们不会一次全部发生,而是顺序发生。因此,当一次更改输入窗口小部件的多个参数时,value可能暂时无效。

技巧是确保更新期间所选日期始终有效。这意味着需要分两个阶段进行更改,并且更改顺序取决于您是在时间上向前还是向后移动。

这是一个可行的解决方案。

library(shiny)
library(tidyverse)
library(lubridate)

ui <- fluidPage(
  selectInput("year", "Select Year:",
              choices = 2010:2020, selected = 2015),
  dateInput("date", "Select Date:", value = NULL)
)

server <- function(input, output, session) {
  observeEvent(input$year, {
    req(input$date, input$year)
    
    # Are we going backwards or forwards?
    if (as.numeric(input$year > year(input$date))) {
      updateDateInput(
        session, 
        "date", 
        max = ymd(paste(input$year, "12-31", sep = "-")),
        value = ymd(paste(input$year, "01-01", sep = "-")),
      )
      updateDateInput(
        session, 
        "date", 
        min = ymd(paste(input$year, "01-01", sep = "-"))
      )
    } else {
      updateDateInput(
        session, 
        "date", 
        min = ymd(paste(input$year, "01-01", sep = "-")),
        value = ymd(paste(input$year, "01-01", sep = "-"))
      )
      updateDateInput(
        session, 
        "date", 
        max = ymd(paste(input$year, "12-31", sep = "-"))
      )
    }
  })
}

shinyApp(ui, server)