DT表格中selectInput组件值无法获取的异常问题求助
DT表格中selectInput无法返回input值的原因与修复方案
核心原因
selectInput默认使用selectize.js生成美化后的下拉组件,而非原生HTML的<select>标签。当你将其转换为字符插入DT表格并动态渲染后,Shiny的bindAll方法无法正确初始化selectize组件,导致组件的值无法传递到input$vect,始终返回NULL。而radioButtons基于原生表单元素,无需额外初始化,因此能正常绑定。
另外,原回调代码中给表格行添加shiny-input-container类属于多余操作,selectInput生成的HTML已经自带该类,重复添加可能干扰Shiny的绑定逻辑。
修复方案
方案1:使用原生select组件(最简单)
修改selectInput的参数,禁用selectize功能,生成原生下拉框:
library(shiny) library(DT) ui <- fluidPage( title = 'Selectinput column in a table', h3("Source: Yihui Xie"), DT::dataTableOutput('foo'), verbatimTextOutput('sel') ) server <- function(input, output, session) { data <- head(iris, 1) for (i in 1:nrow(data)) { data$species_selector[i] <- as.character(selectInput( "vect", label = "", choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), selected = 1, selectize = FALSE # 禁用selectize,使用原生select )) } output$foo = DT::renderDataTable( data, 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]); }); Shiny.unbindAll(table.table().node()); Shiny.bindAll(table.table().node());") ) output$sel = renderPrint({ input$vect }) } shinyApp(ui, server)
方案2:保留selectize美化组件(需手动初始化)
如果需要保留selectize的美化效果,需在回调中手动初始化selectize组件:
library(shiny) library(DT) ui <- fluidPage( title = 'Selectinput column in a table', h3("Source: Yihui Xie"), DT::dataTableOutput('foo'), verbatimTextOutput('sel') ) server <- function(input, output, session) { data <- head(iris, 1) for (i in 1:nrow(data)) { data$species_selector[i] <- as.character(selectInput( "vect", label = "", choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), selected = 1 )) } output$foo = DT::renderDataTable( data, 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]); }); Shiny.unbindAll(table.table().node()); Shiny.bindAll(table.table().node()); // 手动初始化selectize组件 $('#vect').selectize();") ) output$sel = renderPrint({ input$vect }) } shinyApp(ui, server)
额外说明
如果表格有多行,需要给每个selectInput设置唯一ID(比如paste0("vect_", i)),避免DOM中出现重复ID导致绑定异常。例如:
for (i in 1:nrow(data)) { data$species_selector[i] <- as.character(selectInput( paste0("vect_", i), label = "", choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), selected = 1, selectize = FALSE )) }
此时获取值需要对应每个ID,比如input[[paste0("vect_", i)]]。
内容的提问来源于stack exchange,提问作者CharlotteS.
相关产品推荐
相关产品推荐

