【问题标题】:On click expanding of rows of a data table in shiny application is not working, How to solve this在闪亮的应用程序中单击扩展数据表的行不起作用,如何解决这个问题
【发布时间】:2019-10-09 15:42:32
【问题描述】:

我已经编写了一个代码来在闪亮的 R 中创建一个数据表,当我单击感兴趣的行时,它应该展开并显示子行。 但是,这仅适用于我的数据表的最后一行。在前面的行中,只显示了子表的标题,而不是数据。

我的数据表: Data Table

我的输出:My result

callback = JS("table.column(1).nodes().to$().css({cursor: 'pointer'});

// Format cars object into another table
var format = function (d) {
    if (d != null) {
        var result = ('<table id=\"child_' + d[2] + '_' + d[3] +
            '\">').replace('.', '_') + '<thead><tr>'
        for (var col in d[4][0]) {
            result += '<th>' + col + '</th>'
        }
        result += '</tr></thead></table>'
        return result
    } else {
        return '';
    }
}

var format_datatable = function (d) {
    var dataset = [];
    for (i = 0; i <= d[4].length - 1; i++) {
        var datarow = $.map(d[4][i], function (value, index) {
            return [value];
        });
        dataset.push(datarow)
    }
    var subtable = $(('table#child_' + d[2] + '_' +
        d[3]).replace('.', '_')).DataTable({
        'data': dataset,
        'autoWidth': true,
        'deferRender': true,
        'info': false,
        'lengthChange': false,
        'ordering': true,
        'paging': false,
        'scrollX': false,
        'scrollY': false,
        'searching': false
    });
};

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;');
        format_datatable(row.data())
    }
});
")

【问题讨论】:

  • 你能提供数据框吗?使用可重现的代码更容易提供帮助。

标签: javascript r shiny datatables


【解决方案1】:

问题是Description 列中存在空格(尝试扩展第 3 行,它应该可以工作,因为没有空格)。因此 JS 代码生成带有空格的子表的 id,这些 id 是无效的。在下面的代码中,空格被替换为_,并且可以正常工作。此外,通过 replace('.', '_') 替换点(因为带点的 id 无效)不是要走的路,因为这只会替换第一次出现的点。您必须使用全局替换:replace(/\./g, '_')。我还对空白进行了全局替换:replace(/\s/g, '_')

dat <- data.frame(
  ' ' = rep('&oplus;',2),
  Sr = c(1, 2),
  Description = c("A - B", "X - Y"),
  Details = I(list(list(list(Chromosome = "chr18", SNP = "rs2")), 
                   list(list(Chromosome = "chr19", SNP = "rs3"),
                        list(Chromosome = "chr20", SNP = "rs4")))), 
  check.names = FALSE
)

callback = JS(
  "table.column(1).nodes().to$().css({cursor: 'pointer'});",
  "// Format the nested table into another table",
  "var format = function (d) {",
  "  if (d != null) {",
  "    var result = ('<table class=\"display compact\" id=\"child_' + ",
  "                 ((d[2] + '_' + d[3]).replace(/\\s/g, '_')) +",
  "                 '\">').replace(/\\./g, '_') + '<thead><tr>';", 
  "    for (var col in d[4][0]) {",
  "      result += '<th>' + col + '</th>';",
  "    }",
  "    result += '</tr></thead></table>';",
  "    return result;",
  "  } else {",
  "    return '';",
  "  }",
  "}",
  "var format_datatable = function (d) {",
  "  var dataset = [];",
  "  for (i = 0; i < d[4].length; i++) {",
  "    var datarow = $.map(d[4][i], function (value, index) {",
  "      return [value];",
  "    });",
  "    dataset.push(datarow);",
  "  }",
  "  var subtable = $(('table#child_' + d[2] + '_' + d[3])",
  "                   .replace(/\\./g, '_').replace(/\\s/g, '_')).DataTable({",
  "                     'data': dataset,",
  "                     'autoWidth': true,",
  "                     'deferRender': true,",
  "                     'info': false,",
  "                     'lengthChange': false,",
  "                     'ordering': true,",
  "                     'paging': false,",
  "                     'scrollX': false,",
  "                     'scrollY': false,",
  "                     'searching': false,",
  "                     'sortClasses': false,",
  "                     'columnDefs': [{targets: '_all', className: 'dt-center'}]",
  "                   });",
  "};",
  "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;');",
  "    format_datatable(row.data())",
  "  }",
  "});")

datatable(dat, callback = callback, escape = FALSE,
          options = list(
            columnDefs = list(
              list(visible = FALSE, targets = 4),
              list(orderable = FALSE, className = 'details-control', targets = 1)
            )
          ))

【讨论】:

    【解决方案2】:

    在事件中使用表格的jQuery选择器,而不是使用table变量。

    $('.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;');
            format_datatable(row.data())
        }
    });
    

    这应该可以工作

    文档:https://datatables.net/examples/api/row_details.html

    【讨论】:

    • 感谢您的建议,但它似乎不起作用。现在任何行的扩展都没有发生。另外我认为问题更多与 format_datatable 函数有关。
    猜你喜欢
    • 2019-09-22
    • 2018-04-15
    • 2016-08-14
    • 2018-12-06
    • 1970-01-01
    • 2017-07-10
    • 2018-12-29
    • 2020-10-20
    • 2021-11-12
    相关资源
    最近更新 更多