我正在尝试创建一个数据表对象,其中每行都有一个子表。 我遵循 Yihui Xie 给出的Child Rows示例的格式。
这个例子展示了如何传入一个简单的字符串,我什至可以做基本的表格。 但我不想硬编码很多 HTML,因为 R 有很好的工具可以为我编写 HTML。
我的问题是,如果我使用 R 生成 HTML 字符串,当我通过
JS
将其传递到数据表对象时,它会将其读取为文字文本,而不是将其渲染为 HTML。
我确信这是一个简单的解决方案,但使用
htmltools::htmlPreserve
和 htmltools::HTML
不会改变任何东西,我怀疑我必须在 JavaScript 中做一些事情。
DT::datatable({
mtcars$rows <-
paste0("<tr><td>Gas Mileage</td><td>", mtcars$mpg, "</td></tr>",
"<tr><td>Quarter Mile</td><td>", mtcars$qsec, "</td></tr>")
cbind(' ' = '⊕', mtcars)
},
escape = c(-2, -13),
selection = "single",
options = list(
columnDefs = list(
list(visible = FALSE, targets = c(0, 13)),
list(orderable = FALSE, className = 'details-control', targets = 1)
)
),
callback = JS("
table.column(1).nodes().to$().css({cursor: 'pointer'});
var format = function(d) {
return '<table>' +
'<tr><td>Variable</td><td>Value</td></tr>' +
d[13] +
'</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('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
}
});"
)
)
尝试将
escape = c(-2, -13)
替换为 escape = FALSE
。
查看源代码,
escape
变量被传递到escapeData
的datatables
函数中,看起来像这样。希望它能为您提供一些关于如何正确自定义指定应该/不应该转义的内容的指导。 :)
# `i` here is your `escape` variable which can be either TRUE/FALSE,
# indices, or colnames.
escapeData = function(data, i, colnames) {
if (is.null(data) || prod(dim(data)) == 0 || identical(i, FALSE)) return(data)
// see below for definition of convertIdx
i = convertIdx(i, colnames, ncol(data))
# only escape character columns (no need to escape numeric or logical columns)
data[i] = lapply(data[i], function(x) {
if (is.character(x) || is.factor(x)) htmlEscape(x) else x
})
data
}
# convertIdx looks like this:
# convert character indices to numeric
convertIdx = function(i, names, n = length(names), invert = FALSE) {
if (!is.character(i)) return({
if (invert) {
if (is.numeric(i)) -i else if (is.logical(i)) !i else {
stop('Indices must be either character, numeric, or logical')
}
} else i
})
if (is.null(names)) stop('The data must have column names')
o = setNames(seq_len(n), names)
i = o[i]
if (any(is.na(i)))
stop("Some column names in the 'escape' argument not found in data")
if (invert) o[-i] else i
}