如何在Shiny的DT表格中根据输入匹配数据框设置单元格颜色?
可行,实现方案如下
核心思路
通过Shiny响应式数据结合DT包的编辑事件监听,对比用户输入与原始词汇数据,动态为输入单元格设置颜色样式。主要分三步:监听编辑动作、校验输入内容、更新表格样式。
完整代码示例
library(shiny) library(DT) ui <- fluidPage( titlePanel("德语词汇测验"), DTOutput("vocab_quiz") ) server <- function(input, output, session) { # 存储原始词汇对照数据(不对外暴露) original_vocab <- reactiveVal( data.frame( English = c("hello", "world", "cat", "dog", "book"), German = c("hallo", "welt", "katze", "hund", "buch"), stringsAsFactors = FALSE ) ) # 初始化测验表格:展示英文列+用户输入列 quiz_df <- reactiveVal({ df <- original_vocab() df$User_Input <- "" df[, c("English", "User_Input")] }) output$vocab_quiz <- renderDT({ datatable( quiz_df(), editable = list(target = "cell", disable = list(columns = 0)), # 禁止编辑英文列 options = list(dom = "t", ordering = FALSE, pageLength = 5), rownames = FALSE ) %>% # 预定义对错样式 formatStyle( "User_Input", color = styleEqual(c("correct", "incorrect"), c("darkgreen", "darkred")), fontWeight = "bold" ) }) # 监听表格编辑事件,实时校验 observeEvent(input$vocab_quiz_cell_edit, { edit_info <- input$vocab_quiz_cell_edit row_idx <- edit_info$row col_idx <- edit_info$col user_input <- trimws(tolower(edit_info$value)) # 更新用户输入数据 current_df <- quiz_df() current_df[row_idx, col_idx] <- edit_info$value # 对比原始答案,标记对错 correct_answer <- tolower(original_vocab()$German[row_idx]) current_df$style <- ifelse( current_df$User_Input == "" | is.na(current_df$User_Input), "", ifelse(user_input == correct_answer, "correct", "incorrect") ) quiz_df(current_df) # 刷新表格应用样式 replaceData( dataTableProxy("vocab_quiz"), current_df, resetPaging = FALSE, rownames = FALSE ) }) } shinyApp(ui, server)
关键细节说明
- 数据隔离:用
reactiveVal存储原始词汇数据,避免客户端获取到正确答案,保证测验公平性。 - 编辑权限控制:通过
editable参数设置仅允许编辑用户输入列,防止修改题目列。 - 大小写兼容:转换为小写后对比,避免因大小写差异误判错误。
- 样式动态更新:使用
replaceData局部更新表格,无需重新渲染整个组件,提升交互流畅度。
内容的提问来源于stack exchange,提问作者Bálint L. Tóth
相关产品推荐
相关产品推荐

