You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为shinyWidgets的airDatepicker不同选项配置对应日期高亮颜色

实现方案

核心逻辑

  • 服务端用响应式变量存储「日期-选项」的映射关系
  • 自定义CSS定义不同选项对应的日期单元格样式
  • 前端JS监听日期点击事件,根据当前选中的选项为单元格添加对应样式类,同时同步映射关系到服务端
  • 服务端同步全量映射到前端,避免日历翻页后样式丢失

完整可运行代码

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  tags$style(HTML("
  /* 定义不同选项对应的日期样式 */
  .airdatepicker--cell.option-A {
    background-color: #ff4444 !important;
    color: white !important;
  }
  .airdatepicker--cell.option-B {
    background-color: #00C851 !important;
    color: white !important;
  }
  ")),
  tags$script(HTML("
  // 监听日期单元格点击事件
  $(document).on('click', '.airdatepicker--cell.-day-', function() {
    const currentOption = $('#option').val();
    // 移除旧的样式类,添加当前选项对应的样式类
    $(this).removeClass('option-A option-B').addClass(`option-${currentOption}`);
    // 将点击的日期和对应选项同步到服务端
    Shiny.setInputValue('date_click', {
      date: $(this).data('date'),
      option: currentOption
    });
  });

  // 接收服务端的全量映射,刷新所有日期的样式(解决翻页后样式丢失问题)
  Shiny.addCustomMessageHandler('refreshDateStyles', function(mapping) {
    $('.airdatepicker--cell.-day-').each(function() {
      const cellTimestamp = $(this).data('date');
      const cellDate = new Date(cellTimestamp).toISOString().split('T')[0];
      if (mapping[cellDate]) {
        $(this).removeClass('option-A option-B').addClass(`option-${mapping[cellDate]}`);
      }
    });
  });
  ")),
  fluidRow(
    selectInput("option", "Choice?", choices = c("A", "B")),
    airDatepickerInput(
      inputId = "input_dates", label = "Inline:",
      multiple = Inf, inline = TRUE
    )
  )
)

server <- function(input, output, session) {
  # 存储日期与选项的映射关系
  date_option_map <- reactiveVal(list())

  # 监听前端的日期点击事件,更新映射
  observeEvent(input$date_click, {
    current_map <- date_option_map()
    # 转换为标准日期字符串作为key
    date_str <- as.Date(input$date_click$date/1000, origin = "1970-01-01") |> as.character()
    current_map[[date_str]] <- input$date_click$option
    date_option_map(current_map)
    # 通知前端刷新样式
    session$sendCustomMessage("refreshDateStyles", current_map)
  })

  # 日历切换视图/选中日期变更时重新应用样式
  observeEvent(input$input_dates, {
    session$sendCustomMessage("refreshDateStyles", date_option_map())
  })

  # 原示例的调试输出
  observeEvent(input$input_dates, {
    print(sprintf("Selected Dates: %s", paste(input$input_dates, collapse = ", ")))
  })
  observe({
    print(sprintf("Option is now: '%s'", input$option))
  })
}

shinyApp(ui = ui, server = server)

使用说明

  • 选中选项A后点击的日期会自动标记为红色
  • 切换到选项B后点击的日期会自动标记为绿色
  • 已标记的日期不会因为切换选项自动变色,重复点击已标记日期会更新为当前选中选项的颜色
  • 日历翻页后已标记的日期样式会自动恢复

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:45:01