DT中使用⊕ HTML代码初始显示字面量而非符号的问题求助
解决datatable初始显示
⊕字面量而非⊕符号的问题 问题现象
自定义datatable实现点击⊕显示子列表、⊖隐藏子列表的交互功能,交互时符号显示正常,但表格初始加载时,第一列直接显示⊕文本,而非预期的⊕符号,仅在点击该元素后才会正确切换显示⊕/⊖。
问题原因
datatable默认会对单元格内容进行HTML转义处理,初始绑定的⊕被当成纯文本渲染;而点击后通过JavaScript的html()方法设置内容时,浏览器会自动解析HTML实体,因此能正确显示符号。
解决方案
以下两种方案均可解决该问题:
方案1:使用Unicode字符替代HTML实体
直接在初始数据和JS回调中使用⊕和⊖的Unicode编码,避免依赖HTML实体解析:
- 修改
datatable2函数中初始列绑定的代码:
if (nrow(x) > 0) x <- cbind(` ` = "\u2295", x) # \u2295是⊕的Unicode编码
- 修改
.callback2函数中的JS回调代码:
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('\u2295'); // 替换为Unicode⊕ } else { row.child(format(row.data())).show(); td.html('\u2296'); // \u2296是⊖的Unicode编码 } });
方案2:关闭目标列的HTML转义
在datatable的columnDefs中,给存放符号的列(targets=1)添加escape: false配置,告诉datatable不对该列内容进行HTML转义:
columnDefs = list( list(visible = FALSE, targets = c(0,pos)), list(orderable = FALSE, className = "details-control", targets = 1, escape = FALSE), # 关闭该列的HTML转义 list(className = "dt-left", targets = 1:2), list(className = "dt-right",targets = 3:ncol(x)) ),
修改后的完整代码示例(方案1)
datatable2 <- function(x, vars = NULL, opts = NULL, ...) { names_x <- names(x) if (is.null(vars)) stop("'vars' must be specified!") pos <- match(vars, names_x) if (any(map_chr(x[, pos], typeof) == "list")) stop("list columns are not supported in datatable2()") pos <- pos[pos <= ncol(x)] + 1 rownames(x) <- NULL if (nrow(x) > 0) x <- cbind(` ` = "\u2295", x) # 使用Unicode⊕ if(dim(x)[2]==7){ js <- c("function(row, data) {", "if (data[5]>1000 | data[5]<1){", "$('td:eq('+(4)+')', row).html(data[5].toExponential(3));", "}", "}") }else if(dim(x)[2]==9){ js <- c("function(row, data) {", "if (data[6]>1000 | data[6]<1){", "$('td:eq('+(5)+')', row).html(data[6].toExponential(3));", "}", "}") } opts <- c(opts, list( columnDefs = list(list(visible = FALSE, targets = c(0,pos)), list(orderable = FALSE, className = "details-control", targets = 1), list(className = "dt-left", targets = 1:2), list(className = "dt-right",targets = 3:ncol(x) ) ), lengthMenu = list(c(10,25,50,100,-1), c(10,25,50,100,"All")), rowCallback = JS(js), buttons = c('copy', 'csv', 'excel', 'pdf', 'print'), dom = "Bfrtilp" ) ) datatable(x, ..., extensions = "Buttons", options = opts, callback = JS(.callback2(x = x, pos = c(0, pos) ) ) ) } .callback2 <- function(x, pos = NULL) { part1 <- "table.column(1).nodes().to$().css({cursor: 'pointer'});" part2 <- .child_row_table2(x, pos = pos) part3 <- " 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('\u2295'); } else { row.child(format(row.data())).show(); td.html('\u2296'); } });" paste(part1, part2, part3) } .child_row_table2 <- function(x, pos = NULL) { names_x <- paste0(names(x), ":") text <- "var format = function(d) { text = '<div><table >' +" for (i in seq_along(pos)) { text <- paste(text, glue::glue("'<tr>' + '<td>' + '{names_x[pos[i]]}' + '</td>' + '<td>' + d[{pos[i]}] + '</td>' + '</tr>' + ")) } paste0(text, "'</table></div>' return text;};" ) }
内容的提问来源于stack exchange,提问作者Miriam Riquelme Pérez
相关产品推荐
相关产品推荐

