如何删除使用Jstreer软件包渲染的层次树元素?

发布于 2025-02-05 21:21:34 字数 2071 浏览 5 评论 0原文

在运行下面的可重复代码时,用户将层次树顶部“菜单”节点中列出的固定选项拖动元素到下面的“拖动”节点。我试图弄清楚用户如何在本文底部说明的“拖动”节点中删除元素。当前,我将jstree选项设置为contextmenu = true,但是如下所示,我不希望用户在“菜单”节点中修改元素;此外,在“此处的拖动”节点中,用户只能添加,删除和重新排序元素(以及开放的孩子 - 以后再来)。

如何更改它以允许用户删除“菜单”中的元素?我的偏好是简单地将元素拖出网格,鼠标按钮右键单击显示“删除”,但现在不使用“ deal/create/edit”(也许添加“添加”孩子和其他tbd的东西),或者垃圾桶拖入。

可重复的代码:

library(jsTreeR)
library(shiny)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(text = "A", type = "moveable", state = list(disabled = TRUE)),
      list(text = "B", type = "moveable", state = list(disabled = TRUE)),
      list(text = "C", type = "moveable", state = list(disabled = TRUE)),
      list(text = "D", type = "moveable", state = list(disabled = TRUE))
    )
  ),
  list(text = "Drag here:", type = "target", state = list(opened = TRUE))
)
  
checkCallback <- JS(
  "function(operation, node, parent, position, more) {",
  "  if(operation === 'copy_node') {",
  "    if(parent.id === '#' || parent.type !== 'target') {",
  "      return false;", # prevent moving an item above or below the root
  "    }",               # and moving inside an item except a 'target' item
  "  }",
  "  return true;",      # allow everything else
  "}"
)
  
dnd <- list(
  always_copy = TRUE,
  is_draggable = JS(
    "function(node) {",
    "  return node[0].type === 'moveable';",
    "}"
  )
)
  
ui <- fluidPage(jstreeOutput("jstree"))  

server <- function(input, output){
  output[["jstree"]] <- renderJstree({
    jstree(
      nodes, 
      dragAndDrop = TRUE, 
      dnd = dnd, 
      checkCallback = checkCallback, 
      contextMenu = TRUE, # << is there a better way so user can only delete items in the ´Drag here´ list?
      types = list(moveable = list(), target = list())
    )
  })

}  

shinyApp(ui, server)

插图:

“在此处输入图像描述”

In running the reproducible code below, the user drags elements from the fixed options listed in the "Menu" node at the top of the hierarchy tree to the "Drag here" node underneath. I'm trying to figure out how the user can delete elements in the "Drag here" node, as illustrated at the bottom of this post. Currently I set the jstree option to contextMenu = TRUE, but as illustrated below I don't want users to modify elements in the "Menu" node; and further, within the "Drag here" node, users should only be able to add, delete, and reorder elements (and open children - to come later).

How can this be changed to allow the user to delete elements in "Menu"? My preferences would be simply dragging elements off the grid, a mouse button right-click that shows "Delete" but not Edit/Create/Edit for now (perhaps adding "Add child" and other TBD things later), or a trash bin to drag into.

Reproducible code:

library(jsTreeR)
library(shiny)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(text = "A", type = "moveable", state = list(disabled = TRUE)),
      list(text = "B", type = "moveable", state = list(disabled = TRUE)),
      list(text = "C", type = "moveable", state = list(disabled = TRUE)),
      list(text = "D", type = "moveable", state = list(disabled = TRUE))
    )
  ),
  list(text = "Drag here:", type = "target", state = list(opened = TRUE))
)
  
checkCallback <- JS(
  "function(operation, node, parent, position, more) {",
  "  if(operation === 'copy_node') {",
  "    if(parent.id === '#' || parent.type !== 'target') {",
  "      return false;", # prevent moving an item above or below the root
  "    }",               # and moving inside an item except a 'target' item
  "  }",
  "  return true;",      # allow everything else
  "}"
)
  
dnd <- list(
  always_copy = TRUE,
  is_draggable = JS(
    "function(node) {",
    "  return node[0].type === 'moveable';",
    "}"
  )
)
  
ui <- fluidPage(jstreeOutput("jstree"))  

server <- function(input, output){
  output[["jstree"]] <- renderJstree({
    jstree(
      nodes, 
      dragAndDrop = TRUE, 
      dnd = dnd, 
      checkCallback = checkCallback, 
      contextMenu = TRUE, # << is there a better way so user can only delete items in the ´Drag here´ list?
      types = list(moveable = list(), target = list())
    )
  })

}  

shinyApp(ui, server)

Illustration:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦言归人 2025-02-12 21:21:34

您必须使用自定义上下文菜单。您没有查看这些示例,原因是给出了一个示例;-)

我还在checkCallback中添加了条件,以防止“在此处拖动”中的某些副本。

library(jsTreeR)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(
        text = "A",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "B",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "C",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "D",
        type = "moveable",
        state = list(disabled = TRUE)
      )
    )
  ),
  list(
    text = "Drag here:",
    type = "target",
    state = list(opened = TRUE)
  )
)

checkCallback <- JS(
  "function(operation, node, parent, position, more) { console.log(node);",
  "  if(operation === 'copy_node') {",
  "    if(parent.id === '#' || node.parent !== 'j1_1' || parent.type !== 'target') {",
  "      return false;", # prevent moving an item above or below the root
  "    }",               # and moving inside an item except a 'target' item
  "  }",
  "  return true;",      # allow everything else
  "}"
)

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

customMenu <- JS(
  "function customMenu(node) {",
  "  var tree = $('#mytree').jstree(true);", # 'mytree' is the Shiny id or the elementId
  "  var items = {",
  "    'delete' : {",
  "      'label'  : 'Delete',",
  "      'action' : function (obj) { tree.delete_node(node); },",
  "      'icon'   : 'glyphicon glyphicon-trash'",
  "     }",
  "  }",
  "  return items;",
  "}")

jstree(
  nodes, dragAndDrop = TRUE, dnd = dnd, checkCallback = checkCallback,
  types = list(moveable = list(), target = list()),
  contextMenu = list(items = customMenu),
  elementId = "mytree" # don't use elementId in Shiny! use the Shiny id
)

You have to use a custom context menu. You didn't look at the examples cause such an example is given ;-)

I also added a condition in checkCallback, to prevent some copies inside 'Drag here'.

library(jsTreeR)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(
        text = "A",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "B",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "C",
        type = "moveable",
        state = list(disabled = TRUE)
      ),
      list(
        text = "D",
        type = "moveable",
        state = list(disabled = TRUE)
      )
    )
  ),
  list(
    text = "Drag here:",
    type = "target",
    state = list(opened = TRUE)
  )
)

checkCallback <- JS(
  "function(operation, node, parent, position, more) { console.log(node);",
  "  if(operation === 'copy_node') {",
  "    if(parent.id === '#' || node.parent !== 'j1_1' || parent.type !== 'target') {",
  "      return false;", # prevent moving an item above or below the root
  "    }",               # and moving inside an item except a 'target' item
  "  }",
  "  return true;",      # allow everything else
  "}"
)

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

customMenu <- JS(
  "function customMenu(node) {",
  "  var tree = $('#mytree').jstree(true);", # 'mytree' is the Shiny id or the elementId
  "  var items = {",
  "    'delete' : {",
  "      'label'  : 'Delete',",
  "      'action' : function (obj) { tree.delete_node(node); },",
  "      'icon'   : 'glyphicon glyphicon-trash'",
  "     }",
  "  }",
  "  return items;",
  "}")

jstree(
  nodes, dragAndDrop = TRUE, dnd = dnd, checkCallback = checkCallback,
  types = list(moveable = list(), target = list()),
  contextMenu = list(items = customMenu),
  elementId = "mytree" # don't use elementId in Shiny! use the Shiny id
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文