我有一个简单的应用程序,它使用动态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,并且用户需要手动搜索以获取当前年份日期。
有人可以帮我弄清楚为什么会这样吗?
答案 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)