На клик разворачивание строк таблицы данных в блестящем приложении не работает, как это решить - PullRequest
0 голосов
/ 23 мая 2019

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

Моя таблица данных: Таблица данных

Мой вывод: Мой результат

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())
    }
});
")

Ответы [ 2 ]

0 голосов
/ 01 июня 2019

Проблема заключается в наличии пробелов в столбце Description (попробуйте развернуть строку 3, она должна работать, потому что нет пробелов).Таким образом, код JS генерирует идентификаторы дочерних таблиц с пробелами, и эти идентификаторы недопустимы.В приведенном ниже коде пробелы заменены на _, и это работает.Более того, замена точек (поскольку идентификатор с точками недопустим) выполнением replace('.', '_') - это не тот путь, потому что он заменяет только первое вхождение точки.Вы должны использовать глобальную замену: 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)
            )
          ))

enter image description here

0 голосов
/ 23 мая 2019

Вместо использования переменной table используйте jQuery-селектор таблицы в событии.

$('.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

...