如何删除用户在jsTreeR中折叠指定父节点的选项?

How to remove the option for the user to collapse a specified parent node in jsTreeR?

提问人:Village.Idyot 提问时间:1/19/2023 最后编辑:Village.Idyot 更新时间:1/20/2023 访问量:44

问:

关于如何使软件包 jsTreeR 中的特定节点不可折叠,而所有其他节点保持可折叠,如下图所示,有什么建议吗?代码发布在插图下方。

enter image description here

法典:

library(jsTreeR)
library(shiny)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(text = "Dog",type = "moveable",state = list(disabled = TRUE)),
      list(text = "Cat",type = "moveable",state = list(disabled = TRUE))
    )
  ),
  list(text = ">> Drag here <<",type = "target",state = list(opened = TRUE))
)

dnd <- list(
  always_copy = TRUE,
  inside_pos = "last", 
  is_draggable = JS(
    "function(node) {",
    "  return node[0].type === 'moveable';",
    "}"
  )
)

mytree <- jstree(
  nodes, dragAndDrop = TRUE, dnd = dnd,
  types = list(moveable = list(), target = list())
)

ui <- fluidPage(
  # tags$head(tags$script(HTML(script))),
  fluidRow(jstreeOutput("mytree"))
)

server <- function(input, output, session){output[["mytree"]] <- renderJstree(mytree)}

shinyApp(ui, server)
JavaScript R 闪亮的 jstreer

评论


答:

2赞 Stéphane Laurent 1/20/2023 #1

不完美,但有效。为要阻止关闭的节点设置。state = list(opened = TRUE, freezed = TRUE)

library(jsTreeR)

dat <- list(
  list(
    text = "RootA",
    data = list(value = 999),
    icon = "glyphicon glyphicon-folder-open",
    state = list(
      opened = TRUE,
      freezed = TRUE
    ),
    children = list(
      list(
        text = "ChildA1",
        icon = "glyphicon glyphicon-file",
        children = list(
          list(
            text = "XXX"
          )
        )
      ),
      list(
        text = "ChildA2",
        icon = "glyphicon glyphicon-file"
      )
    )
  ),
  list(
    text = "RootB",
    icon = "glyphicon glyphicon-folder-open",
    children = list(
      list(
        text = "ChildB1",
        icon = "glyphicon glyphicon-file"
      ),
      list(
        text = "ChildB2",
        icon = "glyphicon glyphicon-file"
      )
    )
  )
)

jstree(dat) %>%
  htmlwidgets::onRender(c(
    "function(el) {",
    "  $(el).on('close_node.jstree', function (e, data) {",
    "    if(data.node.state.freezed) {",
    "      setTimeout(function(){data.instance.open_node(data.node);}, 0);",
    "    }",
    "  });",
    "}"
  ))
3赞 thothal 1/20/2023 #2

我会在第一个节点上添加一个直接处理程序,用于防止点击事件冒泡,从而关闭父节点。您需要延迟处理程序的分配,b/c 在渲染时节点(以及带有箭头的元素)尚未设置。当节点准备就绪时,外部处理程序会触发,这就是我们分配处理程序的地方。click<i>stopPropagationclick<i>oneclick

mytree %>%
   htmlwidgets::onRender("
      function (el) {
         $(el).one('ready.jstree', function() { 
             // need to wait until all nodes are loaded to assigne event listener
             $(this).find('i').first().on('click', (evt) => evt.stopPropagation()) 
         });
      }")

评论

0赞 Village.Idyot 1/20/2023
是的,这效果很好!对于任何其他 R“新人”,我将 thothal 的解决方案插入到 OP 代码的服务器部分,用 thothal 的解决方案替换内部。效果很好。mytreerenderJstree(mytree)