我试图为从一个层次结构树节点拖入(复制)到另一个节点的元素生成顺序编号,同时给用户在目标节点中放置元素的位置的选项。顺序编号应该反映元素的目标节点顺序,如本文底部的插图所示。可复制代码如下所示。对如何做到这一点有什么建议吗?
请注意,为了代码简洁起见,我删除了一些非常好的特性。但是,当我完成对jsTreeR包的研究后,我将发布全部内容,这样用户就可以看到完整的好处。
这是发布How to pull specific node elements from a jsTree into an R data frame?的后续内容。
可复制代码:
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 = ">>> Drag here <<<",
type = "target",
state = list(opened = TRUE)
)
)
checkCallback <- JS(
"function(operation, node, parent, position, more) { ",
" 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
" }",
" if(operation === 'delete_node') {",
" Shiny.setInputValue('deletion', position + 1);",
" }",
" return true;", # allow everything else
"}"
)
dnd <- list(
always_copy = TRUE,
is_draggable = JS(
"function(node) {",
" return node[0].type === 'moveable';",
"}"
)
)
mytree <- jstree(
nodes, dragAndDrop = TRUE, dnd = dnd, checkCallback = checkCallback,
types = list(moveable = list(), target = list())
)
script <- '
$(document).ready(function(){
$("#mytree").on("copy_node.jstree", function(e, data){
var instance = data.new_instance;
var node = data.node;
var id = node.id;
var index = $("#"+id).index() + 1;
var text = index + ". " + node.text;
Shiny.setInputValue("choice", text);
instance.rename_node(node, text);
});
});
'
library(shiny)
ui <- fluidPage(
tags$head(tags$script(HTML(script))),
fluidRow(
column(width = 4,jstreeOutput("mytree")),
column(width = 8,verbatimTextOutput("choices"))
)
)
server <- function(input, output, session){
output[["mytree"]] <- renderJstree(mytree)
Choices <- reactiveVal(data.frame(choice = character(0)))
observeEvent(input[["choice"]],{Choices(rbind(Choices(),data.frame(choice = input[["choice"]])))})
observeEvent(input[["deletion"]], {Choices(Choices()[-input[["deletion"]], , drop = FALSE])})
output[["choices"]] <- renderPrint({Choices()})
}
shinyApp(ui, server)说明:


编辑响应第一个注释,使用户只能拖动/复制到“拖动此处”节点的最后位置:
可重复的代码( OP中的两个添加部分标记为#注释):
nodes <- list(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( # ADDED A 3rd ELEMENT
text = "C",
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 === '#' || node.parent !== 'j1_1' || parent.type !== 'target') {",
" return false;",
" }",
" }",
" if(operation === 'delete_node') {",
" Shiny.setInputValue('deletion', position + 1);",
" }",
" return true;",
"}"
)
dnd <- list(
always_copy = TRUE,
inside_pos = "last", # ADDED LAST POSITION
is_draggable = JS(
"function(node) {",
" return node[0].type === 'moveable';",
"}"
)
)
mytree <- jstree(
nodes, dragAndDrop = TRUE, dnd = dnd, checkCallback = checkCallback,
types = list(moveable = list(), target = list())
)
script <- '
$(document).ready(function(){
$("#mytree").on("copy_node.jstree", function(e, data){
var instance = data.new_instance;
var node = data.node;
var id = node.id;
var index = $("#"+id).index() + 1;
var text = index + ". " + node.text;
Shiny.setInputValue("choice", text);
instance.rename_node(node, text);
});
});
'
library(shiny)
ui <- fluidPage(
tags$head(tags$script(HTML(script))),
fluidRow(
column(width = 4,jstreeOutput("mytree")),
column(width = 8,verbatimTextOutput("choices"))
)
)
server <- function(input, output, session){
output[["mytree"]] <- renderJstree(mytree)
Choices <- reactiveVal(data.frame(choice = character(0)))
observeEvent(input[["choice"]],{Choices(rbind(Choices(),data.frame(choice = input[["choice"]])))})
observeEvent(input[["deletion"]], {Choices(Choices()[-input[["deletion"]], , drop = FALSE])})
output[["choices"]] <- renderPrint({Choices()})
}
shinyApp(ui, server)现在,通过试图将添加的元素引导到最后一个位置,说明了这个问题:


发布于 2022-06-11 13:11:48
只进入最后一个位置:
checkCallback <- JS(
"function(operation, node, parent, position, more) { ",
" if(operation === 'copy_node') {",
" var n = parent.children.length;",
" if(position !== n || 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
" }",
" if(operation === 'delete_node') {",
" Shiny.setInputValue('deletion', position + 1);",
" }",
" return true;", # allow everything else
"}"
)https://stackoverflow.com/questions/72573608
复制相似问题