简体   繁体   English

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

[英]How do I toggle a cell class in a shiny DT datatable?

Using Shiny and DT, I want to trigger an event for specific cells in a datatable. 我想使用Shiny和DT触发数据表中特定单元格的事件。 Suppose I want the first column to turn red on hover. 假设我希望第一列在悬停时变为红色。 When I create the table I add a callback that registers a hover event on the td elements in the first column. 创建表时,我添加了一个回调,该回调在第一列的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)

From the javascript console if I run the identical code it works : 从javascript控制台,如果我运行相同的代码,则可以运行:

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

Why doesn't this work in the datatable callback? 为什么这在datatable回调中不起作用? What is the right way to do this? 什么是正确的方法?

Usually when you see this sort of behaviour, it suggests a timing issue. 通常,当您看到这种行为时,它暗示了时间问题。 The callback is being called back before the table is fully rendered, the the columns you want to operate on don't exist just quite yet. 在完全渲染表之前将回调该回调,您要对其进行操作的列还不存在。

Remove the callback option and use options = list( drawCallback = JS(...) ) instead. 删除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")}) }')
  )
)

For completeness, here are three solutions: drawCallback , rowCallback , and table.on . 为了完整drawCallback ,这里提供了三种解决方案: drawCallbackrowCallbacktable.on drawCallback was given as the answer, above. 上面给出了drawCallback作为答案。 columnDefs can be used to assign a class to a column, which makes it easy to use selectors. columnDefs可用于将类分配给列,这使选择器的使用变得容易。 rowCallback is an alternative to drawCallback. rowCallbackdrawCallback的替代方法。 And, last, events can be assigned using on() in the datatables API for mouse events, but you must manage both mouseenter and mouseleave instead of jQuery's hover() convenience method. 最后,可以使用datatables API中的on()为鼠标事件分配事件,但是您必须同时管理mouseentermouseleave而不是jQuery的hover()便捷方法。 (I find this last solution perplexing because the documentation (1) does not have a second selector parameter and (2) mouse events are not listed in the events API , but that's what works!) (我发现这最后一个解决方案很困惑,因为文档(1)没有第二个选择器参数, (2)鼠标事件未在events API中列出,但这是可行的!)

Important, only one of these is needed, not all three! 重要的是,只需要其中之一,而不是全部三个! Personally, I like the rowCallback as the most concise. 就个人而言,我最喜欢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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM