折叠行组闪亮

时间:2020-01-24 12:46:25

标签: javascript jquery r shiny datatables

我有一个相当简单的应用程序(如下),我尝试使用具有折叠组功能的DataTable输出分组表。我发现其中的解决方案是在jQuery here中实现的,但我不知道如何将这种复杂的实现转移到R中。

目前,我可以在一个小组中崩溃,但不能崩溃整个小组本身。有什么提示可以在Shiny中实现吗?

我的应用程序:

library(shiny)
library(DT)
library(shinyjs)

ui <- fluidPage(

   # Application title
   titlePanel("Collapse/Expand table"),

            mainPanel(
          DTOutput("my_table")

      )
   )


server <- function(input, output) {

    output$my_table<-DT::renderDataTable({

        datatable(mtcars[1:15,1:5],
                  extensions = 'RowGroup', 
                  options = list(rowGroup = list(dataSrc=c(3)),
                                 pageLength = 20),
                  callback = JS("
                                table.on('click', 'tr', function () {
                                    var rowsCollapse = $(this).nextUntil('.group');
                                    $(rowsCollapse).toggleClass('hidden');
                                 });"))
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

编辑

考虑到AEF注释,可以调整代码以指定甚至在单击表 body 后必须进行的操作。实际上,这会折叠所有行,直到下一组为止。剩下的部分是仅将点击限制在组行上。 回调现在应该是:

callback = JS("$('#DataTables_Table_0 tbody').on('click', 'tr', function () {
 $(this).nextUntil('.group').toggleClass('hidden');});"))

4 个答案:

答案 0 :(得分:2)

事实证明这是DT的javascript代码的错误。有一个单击事件监听器,将记录所有单击单元格的信息。但是,RowGroup扩展会创建一个不属于原始数据集的新行,并导致错误。 此错误停止了进一步的javascript执行。

在您的情况下,tr.group事件由于上一个单元格单击事件引发的错误而无法正常工作。

我们已经修复了该错误,并且DT的开发版本应该可以与以下代码一起使用:

library(shiny)
library(DT)
ui <- fluidPage(# Application title
  titlePanel("Collapse/Expand table"),
  mainPanel(DTOutput("my_table")))

callback_js <- JS(
  "table.on('click', 'tr.dtrg-group', function () {",
  "  var rowsCollapse = $(this).nextUntil('.dtrg-group');",
  "  $(rowsCollapse).toggleClass('hidden');",
  "});"
)

server <- function(input, output) {
  output$my_table <- DT::renderDT({
    datatable(
      mtcars[1:15, 1:5],
      extensions = 'RowGroup',
      options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
      callback = callback_js,
      selection = 'none'
    )
  })
}

# Run the application
shinyApp(ui = ui, server = server)

再次感谢您的举报!

DT的Github问题的通知:https://github.com/rstudio/DT/issues/759

答案 1 :(得分:1)

关于这一点,请另外注意。 我注意到在标准的FluidPage等中,这按预期工作。 但是,当我开始在htmlTemplate中使用它时,它就停止了工作。

一路走来,它失去了.hidden类,我不得不手动添加它。

.hidden {
  display: none !important;
}

然后它按预期工作。

答案 2 :(得分:0)

多亏了AEF的评论,我才得以解决问题。该事件必须发生,一个用户单击主体上的 $('#DataTables_Table_0 tbody'),并且仅单击具有组标识符的行 'tr.group'

必须对最终回调进行调整,以将这两个条件都考虑在内。

因此具有可折叠行的应用程序如下所示:

library(shiny)
library(DT)
library(shinyjs)

ui <- fluidPage(

   # Application title
   titlePanel("Collapse/Expand table"),

            mainPanel(
          DTOutput("my_table")

      )
   )


server <- function(input, output) {

    output$my_table<-DT::renderDataTable({

        datatable(mtcars[1:15,1:5],
                  extensions = 'RowGroup', 
                  options = list(rowGroup = list(dataSrc=c(3)),
                                 pageLength = 20),
                  callback = JS("
                                $('#DataTables_Table_0 tbody').on('click', 'tr.group', function () {
                                    var rowsCollapse = $(this).nextUntil('.group');
                                    $(rowsCollapse).toggleClass('hidden');
                                 });"))
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

答案 3 :(得分:0)

正如@David Joequera在评论中所提到的,这是一个JavaScript错误,其中数据表的默认事件处理程序之一抛出错误,因为在组行中不存在行属性。

作为一种变通办法,我们可以删除此事件处理程序,以便隐藏的事件处理程序起作用。

我也建议您仅使用事件处理程序来定位组行,以便您只能完全关闭和打开组,而不能半隐藏组。您只需在事件监听器目标中添加一个“ .group”即可实现。 产生此代码:

table.on('click', 'tr.group', function () {
   var rowsCollapse = $(this).nextUntil('.group');
   $(rowsCollapse).toggleClass('hidden');
})

为了删除事件处理程序,我们将需要等待,直到表已正确加载并且出现问题的事件处理程序为止,因此我建议使用较小的超时时间。 1000毫秒对我来说很好,应该不会带来任何可用性问题。 因此,将此代码添加到回调中应该可以解决此问题:

setTimeout(function(){$('#DataTables_Table_0').off('click.dt','tbody td')},1000);

请注意,要删除的数据表的ID在最终/实际解决方案中可能会更改

该示例的代码如下:

library(shiny)
library(DT)
library(shinyjs)

ui <- fluidPage(

  # Application title
  titlePanel("Collapse/Expand table"),

  mainPanel(
    DTOutput("my_table")

  ),
)


server <- function(input, output) {

output$my_table<-DT::renderDataTable({

datatable(mtcars[1:15,1:5],
          extensions = 'RowGroup', 
          options = list(rowGroup = list(dataSrc=c(3)),
                         pageLength = 20),
          callback = JS("
                           setTimeout(function(){$('#DataTables_Table_0').off('click.dt','tbody td')},1000);
                           table.on('click', 'tr.group', function () {
                                var rowsCollapse = $(this).nextUntil('.group');
                                $(rowsCollapse).toggleClass('hidden');
                             });"))
})



}

# Run the application 
shinyApp(ui = ui, server = server)