Shiny多页DataTable内嵌Radio Button值无法访问问题咨询
解决Shiny DT分页后无法获取非当前页单选框值的问题
问题根源:DT开启分页后,只有当前页的DOM元素会保留在页面中,初始的callback仅在表格首次渲染时绑定了第一页的Shiny输入元素。切换分页后,新加载的行未重新执行Shiny绑定逻辑,导致无法捕获这些行的单选框输入值。
解决方案:监听DT的分页切换事件(page.dt),每次分页变更时,对当前页的所有行重新执行绑定操作,确保Shiny能识别新渲染的输入元素。
修改后的完整代码:
library(shiny) library(DT) shinyApp( ui = fluidPage( title = 'Radio buttons in a table', DT::dataTableOutput('foo'), verbatimTextOutput('sel') ), server = function(input, output, session) { m = matrix( as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE, dimnames = list(month.abb, LETTERS[1:5]) ) for (i in seq_len(nrow(m))) { m[i, ] = sprintf( '<input type="radio" name="%s" value="%s"/>', month.abb[i], m[i, ] ) } output$foo = DT::renderDataTable( m, escape = FALSE, selection = 'none', server = FALSE, options = list(dom = 'Bfrtip', paging = TRUE, pageLength = 6, ordering = FALSE), callback = JS(" // 封装绑定逻辑函数 var bindRadioRows = function() { table.rows({page:'current'}).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()); }; // 首次加载时绑定当前页元素 bindRadioRows(); // 监听分页切换事件,重新绑定当前页元素 table.on('page.dt', function() { bindRadioRows(); }); ") ) output$sel = renderPrint({ str(sapply(month.abb, function(i) input[[i]])) }) } )
关键改动说明:
- 把绑定逻辑封装为
bindRadioRows函数,便于重复调用 - 使用
table.rows({page:'current'})仅处理当前页的行,避免无效操作 - 监听
page.dt事件,每次分页切换时自动执行绑定函数,确保新渲染的行被Shiny识别 - 保留
server = FALSE,确保所有数据加载到客户端,分页仅做DOM切换而非后端数据请求
验证结果:切换到任意分页页面,选择单选框后,verbatimTextOutput会实时显示对应月份的选中值,所有页面的输入均可正常捕获。
内容的提问来源于stack exchange,提问作者loup piedfer
相关产品推荐
相关产品推荐

