如何在闪亮的DT数据表中切换单元格类?

时间:2018-11-03 15:23:12

标签: r datatables shiny dt

使用Shiny和DT,我想触发数据表中特定单元的事件。假设我希望第一列在悬停时变为红色。创建表时,我添加了一个回调,该回调在第一列的td元素上注册了一个悬停事件。

library(shiny)
library(DT)

ui <- fluidPage(
  tags$head(tags$style(HTML(".red { background-color: red; }"))),
  DT::dataTableOutput("iris")
)

server <- function(input, output) {
  output$iris <- DT::renderDataTable(DT::datatable(iris, callback = JS("
table.column(0).nodes().to$().hover(function(){$(this).toggleClass('red');});
")))
}

shinyApp(ui = ui, server = server)

如果我运行相同的代码,则从javascript控制台运行:

table=$('#DataTables_Table_0').DataTable()
table.column(0).nodes().to$().hover(function(){$(this).toggleClass('red');});

为什么这在datatable回调中不起作用?正确的方法是什么?

2 个答案:

答案 0 :(得分:2)

通常,当您看到这种行为时,它暗示了时间问题。在完全渲染表之前将回调该回调,您要操作的列还不存在。

删除callback选项,改用options = list( drawCallback = JS(...) )

DT::datatable(
  iris,
  options = list(
    drawCallback = JS('function() {this.api().table().column(0).nodes().to$().hover(function(){$(this).toggleClass("red")}) }')
  )
)

答案 1 :(得分:0)

出于完整性考虑,这里提供了三种解决方案:drawCallbackrowCallbacktable.on。上面给出了drawCallback作为答案。 columnDefs可用于将类分配给列,这使选择器的使用变得容易。 rowCallback是drawCallback的替代方法。最后,可以使用datatables API中的on()来为鼠标事件分配事件,但是您必须同时管理mouseentermouseleave而不是jQuery的hover()便捷方法。 (我发现这最后一个解决方案很困惑,因为文档(1)没有第二个选择器参数 (2)鼠标事件未在events API中列出,但这是可行的!)

重要的是,只需要其中之一,而不是全部三个!就我个人而言,我最喜欢rowCallback

library(shiny)
library(DT)

ui <- fluidPage(
  tags$head(tags$style(HTML(".red { background-color: red; }"))),
  div(id='tbl1', DT::dataTableOutput("iris"))
)

server <- function(input, output) {
  output$iris <- DT::renderDataTable(DT::datatable(iris, 
                                                   options = list(drawCallback=JS("function() { this.api().table().column(0).nodes().to$().hover(function(){$(this).toggleClass('red');}); }"),
                                                                  rowCallback=JS("function(row) { $(row).children('.firstcol').hover(function(){$(this).toggleClass('red')}) }"),
                                                                  columnDefs=list(list(className='firstcol', targets=0))),
                                                    callback = JS("
 table.on('mouseenter', 'td.firstcol', function() { $(this).addClass('red'); });
 table.on('mouseleave', 'td.firstcol', function() { $(this).removeClass('red'); });
")))
}

shinyApp(ui = ui, server = server)