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

如何在Reactable中实现含行内单选按钮的回调功能?

Reactable表格中绑定单选按钮并获取Shiny输入值的实现思路

已通过DT实现带单选按钮组的表格并获取用户选择,但Reactable的实现逻辑与DT不同,核心是要手动让Shiny识别表格内的单选按钮输入元素。以下是具体实现步骤及完整代码:

关键实现要点

  • 保持单选按钮命名一致性:和DT中逻辑一致,每行的单选按钮组使用filter_names中的值作为name属性,确保Server端可通过input[[name]]获取对应选择值
  • 启用HTML渲染:通过colDef(html = TRUE)让Reactable解析HTML格式的单选按钮
  • 手动绑定Shiny输入:Reactable渲染完成后,调用Shiny.bindAll将表格内的输入元素绑定到Shiny,这一步类似DT的callback逻辑,需借助htmlwidgets::onRender添加渲染回调
  • Server端获取值:与DT方式完全一致,直接通过input[[filter_name]]获取每行的单选选择结果

完整修改后代码

library(shiny)
library(DT)
library(reactable)
library(htmlwidgets) # 用于添加Reactable的渲染回调

filter_names <- row.names(mtcars)
shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    h5("DT table"),
    DT::dataTableOutput('foo'),
    tableOutput('sel'),
    hr(),
    h5("Reactable"),
    reactableOutput("foo_reactable")
    
  ),
  server = function(input, output, session) {
    
    values <- reactiveValues()
    
    m = matrix(
      c("1","0","2"), nrow = length(filter_names), ncol = 3, byrow = TRUE,
      dimnames = list(filter_names,c("Include","Exclude","Ignore")))
    
    for (i in seq_len(nrow(m))) {
      m[i, ] = sprintf(
        '<input type="radio" name="%s" value="%s" checked="checked"/>',filter_names[i], m[i, ])}
    
    m_dat <- as.data.frame(m)
    m_dat$var <- filter_names
    
    output$foo = DT::renderDataTable(
      m_dat, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 't', paging = FALSE, ordering = FALSE),
      callback = JS("table.rows().every(function(i, tab, row) {
          var $this = $(this.node());
          $this.attr('id', this.data()[0]);
          $this.addClass('shiny-input-radiogroup');
        });
        Shiny.unbindAll(table.table().node());
        Shiny.bindAll(table.table().node());")
    )
    
    output$sel = renderTable({
      out <- cbind(filter_names, unlist(sapply(filter_names, function(i) {input[[i]]})))
      colnames(out) <- c("变量名", "选择值")
      out
    })
    
    output$foo_reactable = renderReactable({
      reactable(m_dat,
                columns = list(
                  Include = colDef(html = TRUE),
                  Exclude = colDef(html = TRUE),
                  Ignore = colDef(html = TRUE)
                )) %>%
        # 添加渲染完成后的JS回调,绑定Shiny输入元素
        onRender("function(el, x) {
          Shiny.bindAll(el);
        }")
    }) 
  } 
)

代码说明

  • 引入htmlwidgets包是为了使用onRender方法,这是给Reactable添加自定义JS逻辑的标准方式
  • onRender中的Shiny.bindAll(el)会将Reactable的DOM元素内所有输入组件绑定到Shiny,确保输入值能被Server端捕获
  • 此时Server端的input[[filter_name]]可正常获取对应行的单选选择,和DT的使用逻辑完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:16:08