Как мне переключить класс ячеек в блестящем DT данных? - PullRequest
0 голосов
/ 03 ноября 2018

Используя 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');});

Почему это не работает в режиме обратного вызова с датами? Как правильно это сделать?

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Для полноты представляем три решения: drawCallback, rowCallback и table.on. drawCallback было дано в качестве ответа выше. columnDefs может использоваться для назначения класса столбцу, что упрощает использование селекторов. rowCallback является альтернативой drawCallback. И, наконец, события могут быть назначены с помощью on () в API datatables для событий мыши, но вы должны управлять как mouseenter, так и mouseleave вместо удобного метода jQuery hover(). (Это последнее решение вызывает недоумение, поскольку в документации (1) нет второго параметра селектора и (2), события мыши не перечислены в 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)
0 голосов
/ 03 ноября 2018

Обычно, когда вы видите такое поведение, оно предлагает проблему синхронизации. Обратный вызов вызывается до того, как таблица будет полностью обработана, столбцы, с которыми вы хотите работать, еще не существуют.

Удалите параметр 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")}) }')
  )
)
...