如何在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
相关产品推荐
相关产品推荐

