【问题标题】:dnd, how to restrict dropping to certain node types?dnd,如何限制丢弃到某些节点类型?
【发布时间】:2012-06-12 15:43:19
【问题描述】:

我有 37 种不同的节点类型。 我正在尝试实现拖放。 这可行,但我需要准确限制可以拖动哪些类型以及可以删除它们的位置。 不幸的是,我在文档中找不到任何有用的信息 (http://www.jstree.com/documentation)。

到目前为止,我已经尝试了三种方法:

首先:根据节点类型在drag_check回调中定义true或false的返回值:

$("#demo1").jstree({
    "dnd" : {
        "drag_check" : function () {

第二个:绑定到 prepare_move.jstree 事件并根据节点类型返回 true 或 false 值:

.bind("prepare_move.jstree", function (e, data) {
   if (data.rslt.o.attr("typ") === "tpop") {

第三:使用类型插件并在那里定义有效的孩子:

$("#tree").jstree( {
    "types": {
        "type_attr": "typ",
        "valid_children": ["ap_ordner_pop", "ap_ordner_apziel", "ap_ordner_erfkrit", "ap_ordner_apber", "ap_ordner_ber", "ap_ordner_beob", "iballg", "ap_ordner_ibb", "ap_ordner_ibartenassoz"],
        "types": {
        "ap_ordner_pop": {
            "valid_children": "pop"
        },
        "pop": {
            "valid_children": ["pop_ordner_tpop", "pop_ordner_popber", "pop_ordner_massnber"],
            "new_node": "neue Population"
        },
        "pop_ordner_tpop": {
            "valid_children": "tpop"
        }

但我仍然可以在几乎任何地方删除大多数节点。 这必须怎么做? 或者你能给我举一个很好的例子吗?

非常感谢您的帮助。

【问题讨论】:

    标签: jstree


    【解决方案1】:

    对于那些使用 jstree v3 寻找答案的人。 crrm 插件已被删除,您将需要使用“check_callback”。

    就我而言,我想做的只是阻止子项被拖到其他子项中。可能有更好的方法来做到这一点,但经过几个小时的进展,这对我有用。

    我相信您还需要将 'check_while_dragging' dnd 选项设置为 true,以便在拖动时触发 'check_callback'。

    这是我的 jsTree 初始化:

    $("#jsTree").jstree({
                'core': {
                    'data': window.treeData,
                    'themes': {
                        'icons': false
                    },
                    'check_callback': function(operation, node, node_parent, node_position, more) {
                        // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
                        // in case of 'rename_node' node_position is filled with the new node name
    
                        if (operation === "move_node") {
                            return node_parent.original.type === "Parent"; //only allow dropping inside nodes of type 'Parent'
                        }
                        return true;  //allow all other operations
                    }
                },
                "state": { "key": "<%=Request.QueryString["type"]%>_infotree" },
                "dnd": {
                    check_while_dragging: true
                },
                "plugins": ["state", "dnd", "types"]
            })
    

    【讨论】:

    • 这并没有像我预期的那样工作。当我从回调中返回 false 时,它​​确实会阻止将源项目添加到父项目。但是,我希望在将鼠标悬停在目标节点上时会看到一个“红色 X”,表示不允许这样做。相反,我看到了一个绿色的复选标记,这使得我看起来可以拖放到目标上,而当我放下它时,什么也没有发生。不想花太多时间在上面,我只是在事件发生时添加了一条警报,上面写着“不允许拖放到此节点上”。
    • 感谢您提供有关版本 3 的信息。我是新手,很难弄清楚不同版本的可用内容。
    • @izmaxx,我注意到如果您尝试将节点拖动到列表中的第一项之前,则不会发生任何事情。但是,如果您在列表中的第一个项目之后拖动一个项目,则该项目被移动。为了解决这个错误,我使用排序插件并按“订单”属性排序,然后在我的服务器上处理新排序的列表,并将新的排序列表发送回 UI。当提交到服务器时,如果项目被拖到父项上,则将项目插入到列表的前面。然后我将新订单发送回前端并重写树
    • @izmaxx 或@tonic,你有没有想过如何使用check_callback() 或其他方式将“红色X”更改为“绿色✓”?
    • @daniel.caspers 将 check_while_dragging 设置为 true 让我得到了红十字会。
    【解决方案2】:

    在目标上,您需要检查是否允许将对象放在那里。正如您所指出的,您似乎有某种机制可以闻到物体的味道:

     if (data.rslt.o.attr("typ") === "tpop")
    

    这很好。在执行多树操作时,使用该技术将一种对象类型与另一种对象类型区分开来。在下面的示例中,我使用来自源和目标的类名来进行我自己独特的“气味测试”。不要复制和粘贴,否则您会感到困惑。您需要使用自己的测试类型来接受/拒绝从一棵树拖放到另一棵树。我所有的测试都是在 crrm check_move 函数中完成的。

    .jstree({
     "crrm" : {
        input_width_limit : 200,
        move : {
            always_copy     : "multitree", // false, true or "multitree"
            open_onmove     : false,
            default_position: "last",
            check_move      : function (m) { 
                                if(!m.np.hasClass("someClassInTarget")) return false;
                                if(!m.o.hasClass("someClassInSource")) return false;
                                return true;
                              }
        }
     },
     "dnd" : {
        copy_modifier   : $.noop,
        drop_target     : ".someWrapperClassInSource",
        drop_check      : function (data) { return true; },
        drop_finish     : function (data) {
                                $.jstree._reference(this.get_container()).remove($(data.o));
                          },
        drag_target     : ".someClassInSource",
        drag_finish     : function (data) {;},
        drag_check      : function (data) { return { after : false, before : false, inside : true }; }
     },
    

    【讨论】:

    • 是的,crrm 的 check_move 有效!非常感谢您的帮助,MMeah。我希望文档在这一点上更清楚
    • 是的,文档不是很清楚。您必须查看源代码才能找到此信息。搜索来源:“check_move”
    • 在 jsTree 文档中也经历过同样的事情——它们并没有想象的那么清晰。 +1 check_move
    • 已经使用 jsTree v3 几个星期了,我自己不喜欢文档。我闻到了 Internet Explorer 的味道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多