diff --git a/DESCRIPTION b/DESCRIPTION index f33ca1a8..52b1398c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: DT Type: Package Title: A Wrapper of the JavaScript Library 'DataTables' -Version: 0.23.1 +Version: 0.23.2 Authors@R: c( person("Yihui", "Xie", email = "xie@yihui.name", role = c("aut", "cre")), person("Joe", "Cheng", role = "aut"), diff --git a/NEWS.md b/NEWS.md index 7712322d..292ab37a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ - Fixed a bug with missing numeric values rendered as `0` (thanks, @tverbeke, #1000). +- Box scalar elements of 'list' columns so that, e.g., `data.frame(col = I(integer(), 1, 2:3))` is represented in JavaScript as `[[], [1], [2, 3]]` instead of `[[], 1, [2, 3]]` (thanks, @mtmorgan, #1005). + # CHANGES IN DT VERSION 0.23 - Make sure number inputs return numeric values when editing numeric table cells (thanks, @stla, #987). diff --git a/R/datatables.R b/R/datatables.R index d49f8bd1..2d8c7795 100644 --- a/R/datatables.R +++ b/R/datatables.R @@ -234,6 +234,9 @@ datatable = function( # applied to the "original" column names, instead of the "modified“ ones, e.g., via the `colnames` arg options[["columnDefs"]] = colDefsTgtHandle(options[["columnDefs"]], base::colnames(data)) + # box scalar elements of list columns + data = boxListColumnAtomicScalars(data) + # align numeric columns to the right if (length(numc)) { # if the `className` of the column has already been defined by the user, diff --git a/R/utils.R b/R/utils.R index 691c2db2..61e3f260 100644 --- a/R/utils.R +++ b/R/utils.R @@ -38,6 +38,25 @@ captionString = function(caption) { if (length(caption)) caption } +# 'box' list column atomic scalars so that the data are represented +# consistently (as arrays) in javascript, e.g., +# data.frame(col = I(list(integer(), 1, 2:3))) --> [[], [1], [2, 3]] +# instead of [[], 1, [2, 3]] +boxAtomicScalarElements = function(x) { + is_atomic = vapply(x, is.atomic, logical(1)) + if (all(is_atomic)) { + is_scalar = lengths(x) == 1L + x[is_scalar] = lapply(x[is_scalar], list) + } + x +} + +boxListColumnAtomicScalars = function(x) { + is_list = vapply(x, is.list, logical(1)) + x[is_list] = lapply(x[is_list], boxAtomicScalarElements) + x +} + toJSON = function(...) { FUN = getFromNamespace('toJSON', 'htmlwidgets') FUN(...)