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

如何在R Shiny仪表盘的数据表每行添加可追踪文本框?

在Shiny DT数据表中实现每行文本框的输入追踪

要实现DT数据表每行文本框的输入追踪,核心是给每个文本框绑定触发事件,把输入内容和对应行的标识一起传递给Shiny服务器。以下是修改后的完整代码:

library(shiny)
library(DT)

shinyApp(
    ui <- fluidPage(
        DT::dataTableOutput("data"),
        textOutput('textInputStatus')
    ),
    
    server <- function(input, output) {
        # 存储每行文本框的输入内容
        textInputs <- reactiveValues(data = list())
        
        shinyInput <- function(FUN, len, id, ...) {
            inputs <- character(len)
            for (i in seq_len(len)) {
                if(FUN == textInput){
                    # 给文本框添加oninput事件,传递ID和输入值
                    inputs[i] <- as.character(FUN(paste0(id, i), ..., 
                        oninput = 'Shiny.onInputChange("text_input", {id: this.id, value: this.value})'))
                } else {
                    inputs[i] <- as.character(FUN(paste0(id, i), ...))
                }
            }
            inputs
        }
        
        df <- reactiveValues(data = data.frame(
            Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
            Motivation = c(62, 73, 3, 99, 52),
            Actions = shinyInput(actionButton, 5, 'button_', label = "Fire", 
                onclick = 'Shiny.onInputChange("select_button",  this.id)' ),
            TextInput = shinyInput(textInput, 5, 'text_', label = "", value = "" ),
            stringsAsFactors = FALSE,
            row.names = 1:5
        ))
        
        output$data <- DT::renderDataTable(
            df$data, server = FALSE, escape = FALSE, selection = 'none',
            # 调整列宽,避免文本框被挤压
            options = list(columnDefs = list(list(width = '150px', targets = 3)))
        )
        
        # 监听按钮点击(保留原有功能)
        observeEvent(input$select_button, {
            selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
            showNotification(paste("已触发对", df$data[selectedRow, 1], "的操作"))
        })
        
        # 监听文本框输入
        observeEvent(input$text_input, {
            # 解析行号
            rowNum <- as.numeric(strsplit(input$text_input$id, "_")[[1]][2])
            # 存储对应行的输入内容
            textInputs$data[[rowNum]] <- input$text_input$value
            # 也可以直接更新数据表中的值(可选)
            # df$data[rowNum, "TextInputValue"] <- input$text_input$value
        })
        
        # 展示文本框输入状态
        output$textInputStatus <- renderText({
            inputRows <- names(textInputs$data)
            if(length(inputRows) == 0){
                "暂无文本输入"
            } else {
                paste0("已输入内容的行:", 
                    paste(sapply(inputRows, function(row){
                        paste(df$data[row, 1], ":", textInputs$data[[row]])
                    }), collapse = ";"))
            }
        })
    }
)

关键改动说明:

  • 给文本框添加oninput事件:在生成textInput时,通过oninput属性调用Shiny.onInputChange,将文本框的ID和当前输入值以对象形式传递给服务器端的input$text_input
  • 解析行号和输入值:在observeEvent(input$text_input)中,通过拆分文本框ID获取对应行号,同时提取输入值
  • 存储输入内容:用reactiveValues存储每行的输入值,方便后续在其他模块中调用;也可以直接更新数据表的对应列
  • 优化显示:调整DT列宽避免文本框被挤压,同时添加文本输出展示输入状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:07