I've already raised the issue here and here. By now a workaround exists however, I still don't understand the root cause.
When running the following app using the latest CRAN version of library(shiny)
and library(jsTreeR)
(2.5.0) after resizing the browser window this error can be seen in the browser console:
Example app:
library(jsTreeR)
library(shiny)
nodes <- list(
list(
text = "Fruits",
type = "fruit",
children = list(
list(
text = "Apple",
type = "fruit",
data = list(
quantity = 20
)
),
list(
text = "Banana",
type = "fruit",
data = list(
quantity = 31
)
),
list(
text = "Grapes",
type = "fruit",
data = list(
quantity = 34
)
)
),
state = list(
opened = TRUE
)
)
)
grid <- list(
columns = list(
list(
width = 200,
header = "Product"
),
list(
width = 150,
value = "quantity",
header = "Quantity"
)
)
)
ui <- fluidPage(
titlePanel("jsTree grid"),
jstreeOutput("jstree")
)
server <- function(input, output, session){
output$jstree <- renderJstree(jstree(nodes, search = TRUE, grid = grid))
}
shinyApp(ui, server)
This is only the case when jstree
is provided with the grid
parameter.
@StéphaneLaurent identified that the class shiny-bound-output
is assigned to the jstree-grid-wrapper
div which causes the issue and that removing it prevents the error.
I'd like to understand why this class is added in the first place and if there is a proper way to implement the grid
parameter without running into this issue.
I think the answer is in the file jstreegrid.js, in the listener of the ready.jstree
event, code starting at line 493:
.on(
"ready.jstree",
$.proxy(function (e, data) {
// find the line-height of the first known node
var anchorHeight = this.element
.find("[class~='jstree-anchor']:first")
.outerHeight(),
q,
cls = this.element.attr("class") || "";
$(
'<style type="text/css">div.jstree-grid-cell-root-' +
this.rootid +
" {line-height: " +
anchorHeight +
"px; height: " +
anchorHeight +
"px;}</style>"
).appendTo("head");
// add container classes to the wrapper - EXCEPT those that are added by jstree, i.e. "jstree" and "jstree-*"
q = cls.split(/\s+/).map(function (i) {
var match = i.match(/^jstree(-|$)/);
return match ? "" : i;
});
this.gridWrapper.addClass(q.join(" "));
}, this)
);
In this code, cls = this.element.attr("class")
is the character string made of all classes attributed to the tree, separated by a white space. Then q = cls.split(/\s+/).map(...
is the array of all these classes except the jstree
class and the classes started with jstree-
, and these classes are then added to the grid (the jstree-grid-wrapper
div). And then I see two possibilities:
at this stage, the tree already has the shiny-bound-output
class, which is then added to the grid;
or the tree does not have the shiny-bound-output
class yet, but it has the class jstreer
, and then htmlwidgets adds the class shiny-bound-output
to all elements having the jstreer
class.
I've just checked, and the tree has both classes shiny-bound-output
and jstreer
at this stage.
A possible solution is to modify jstreegrid.js so that it does not copy these classes to the grid. In fact I don't see any other solution.