首页 > 解决方案 > 通过 R DT::datatables 中的 JS 回调呈现 HTML

问题描述

在这里处理 tomasreigl 的示例(https://github.com/rstudio/DT/issues/393#issuecomment-279627237),我认为由于基本的 JS 问题,我有一个不起作用的细微变化。

创建数据

library(DT)
dataSet <- data.frame(name=c("Jack", "Jill"),
                  age=c(25,25),
                  tableHtml=c("<table><tr><th>Value A</th><th>Value B</th></tr><tr><td>1</td><td>2</td></tr></table>",
                              "<div><table><tr><th>Value A</th><th>Value B</th></tr><tr><td>3</td><td>4</td></tr></table></div>"),
                  stringsAsFactors=FALSE)'

方法 1,在 DT 表中渲染 HTML 表 WORKING,但不是我需要的

现在,我想做的是将 html 表渲染为 DT 交互式表中每一行的嵌套子级。第一个块有效,但显然会为每个 DT 行呈现相同的表,因为 HTML 在回调中是硬编码的:

## Working, but same child table for every row
DT::datatable(
    cbind(' ' = '&oplus;', dataSet),
    escape = -2,
    options = list(
        columnDefs = list(
            list(visible = FALSE, targets = c(0,4)),
            list(orderable = FALSE, className = 'details-control', targets = 1)
        )
    ),
    callback = JS("
                  table.column(1).nodes().to$().css({cursor: 'pointer'});
                  var format = function(d) {
                    return '<div><table><tr><th>Value A</th><th>Value B</th></tr><tr><td>1</td><td>2</td></tr></table></div>'
                  };
                  table.on('click', 'td.details-control', function() {
                    var td = $(this), row = table.row(td.closest('tr'));
                      if (row.child.isShown()) {
                        row.child.hide();
                        td.html('&oplus;');
                      } else {
                        row.child(format(row.data())).show();
                        td.html('&CircleMinus;');
                      }
                    });"
                  )
)

方法 2 为每一行渲染不同的 HTML 表不起作用

进入tableHtml数据框的列dataSet。对于数据框的每一行,dataSet我想使用tableHtml数据框列中的 HTML 渲染一个 DT 表行,其中一个子行包含一个表dataSet。下面,我尝试只返回d[4],但返回原始 HTML 而不呈现表格。

## Attempt at different child table for each row
datatable(
    cbind(' ' = '&oplus;', dataSet),
    escape = -2,
    options = list(
        columnDefs = list(
            list(visible = FALSE, targets = c(0,4)),
            list(orderable = FALSE, className = 'details-control', targets = 1)
        )
    ),
    callback = JS("
                  table.column(1).nodes().to$().css({cursor: 'pointer'});
                  var format = function(d) {
                    return d[4]
                  };
                  table.on('click', 'td.details-control', function() {
                    var td = $(this), row = table.row(td.closest('tr'));
                      if (row.child.isShown()) {
                        row.child.hide();
                        td.html('&oplus;');
                      } else {
                        row.child(format(row.data())).show();
                        td.html('&CircleMinus;');
                      }
                    });"
                  )
)

我尝试了大约 20 种变体,但没有一个能按预期工作。事实上,我对 thomasreigl 示例的第一次修改确实有效,这让我认为这只是一个超出我能力范围的 JS 小问题。任何帮助表示赞赏。

标签: javascripthtmlrdt

解决方案


好吧,还有 2 个小时的摆弄,结果变成了escape = -2成功escape = FALSE的秘诀。


推荐阅读