Drag and Drop between two jstrees

1,316 views
Skip to first unread message

Stephan Wilms

unread,
Mar 20, 2014, 4:24:36 AM3/20/14
to jst...@googlegroups.com
Hi,

I'd like to implement a solution where the user can drag node from a one tree into a second tree, but just generally into the tree, not onto any particular node. Also dropping onto the tree where drag started should not be possible.

The things I can not figure out are:

1) It does not seem possible to allow dropping onto a jstree anywhere outside the nodes. When you hover with your dragged items outside the jstree area covered by nodes the "check_callback" does not get called and the drag icon is the "not allowed" icon (ie. the red X).

2) How do I prevent the insertion point marker from apearing ? I want to implement my own functionality for what happens when the nodes get released. This will not be in anyway related to the location where the dragged nodes get release and therefore showing the insertion marked (the little mobile triangle) is misleading and gives the wrong impression to the user.

3) How can I disallow dropping nodes that are being dragged onto the tree where the drag started ? I only want to alow dragging from one tree to a second tree (both ways) ?

Thanks for any help :-)

Regards,
Stephan

Ivan Bozhanov

unread,
Mar 20, 2014, 5:05:14 AM3/20/14
to jst...@googlegroups.com
You can achieve most of this using check_callback and binding to dnd_move:
check_callback : function (chk, obj, par, pos, more) { if(more && more.dnd) { return false; } }

// bind AFTER you create the tree
$(document).bind('dnd_move.vakata', function (e, data) {
  if(data.event.target).closest('.jstree').length) {
    data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-er').addClass('jstree-ok');
  }
});
$(document).bind('dnd_stop.vakata', function (e, data) {
  if(data.event.target).closest('.jstree').length) {
    // process the drop on the other tree
  }
});

This bypasses the actual DND plugin, so you can simply leave it out and start the drag yourself - so remove dnd, remove the check_callback from above, keep the dnd_move & dnd_stop handlers and add this:
        $(document)
            .on('mousedown', '.jstree-anchor', function(e) {
                return $.vakata.dnd.start(e, {'jstree': false, 'obj': $(this), 'nodes': [{id: true, text: $(this).text(), 'data': {'more': 'stuff'}}]}, '<div id="jstree-dnd" class="jstree-default"><i class="jstree-icon jstree-er"></i>' + $(this).text() + '</div>');
            });

Best regards,
Ivan

Charles

unread,
Nov 26, 2015, 10:51:33 AM11/26/15
to jsTree
Hi Ivan,

Thank you for the wonderful work you have done with jsTree.

I have a scenario similar to Stephan above.... and I could use some help.

This is what I am trying to design

two trees side by side but with different characteristics and drag and drop abilities

Left Tree j1 Right Tree j2

Directory [] Home
  file1     file3
  file2     file2
  file3 [] Work
  file4     file1
             file4


On the left tree (j1):

The left tree will be populated by a file directory and show files 

I want the user to be able to copy and drop nodes from the left tree to the right.  (Got this working - copy over to the right node but not move)
I want Sort on the left tree so user can find files by name easier (Got this working)

this is the code for the left tree j1:


            $(function () {
                $("#j1").jstree({
                    "core": {
                        "check_callback": true,
                        "expand_selected_onload": true,
                        "data": [{ "text": "Documents", "type": "Documents", "children": [{ "text": "Packages", "type": "Packages" }] }]
                    },
                    "dnd": {
                        "always_copy": true,
                    },
                    "plugins": ["dnd", "types", "contextmenu", "sort", "unique", "search"],

                    "types": {
                        "#": {
                            "valid_children": ["Documents"]
                        },
                        "Documents": {
                            "valid_children": ["Packages"]
                        },
                        "Packages": {
                            "valid_children": ["Items"]
                        },
                        "Items": {
                            "valid_children": []
                        }
                    }
                });


On the right tree (j2):

The right tree will be populated by a database query and shows named collections of file names

I need checkboxes of the parent nodes only (the named collection of file names, ie.. "Home" and "Work" in example above) (Need Help - I have gotten checkbox to display but NOT only for the parent node level)

I need the user to be able to drag and drop at the same node level only within the right tree only, this is so the file names within a 'named collection' can be reordered (Need Help have no idea what to do)
ie, drag and drop within the right tree only and same node level only Example change the order of the named collection 'Work' file names as below file4 is now above file1

left tree j1 right tree j2

Directory [] Home
  file1     file3
  file2     file2
  file3 [] Work
  file4     file4
             file1


               [TRASH CAN]


(I do not have sort on the right tree - user is responsible for specifying order)

On the right tree I need a way for the user to delete a given file name, right mouse click and selecting delete is okay, but having a trash can icon and allowing them to drag is better (more visually intuitive)

This is the code so far for the right tree j2:

                $("#j2").jstree({
                    "core": {
                    "check_callback": function (o, n, p, pos, more) {
                        if(more && more.dnd && more.is_multi) { return false; }
                        return true;
                    },
                        "expand_selected_onload": true,
                        "data": [{ "text": "Jobs", "type": "Jobs", "children": [{ "text": "Packages", "type": "Packages" }] }]
                    },
                    "dnd": {
                        'is_draggable': false,
                    },
                    "plugins": ["dnd", "types", "contextmenu", "checkbox"],

                    "types": {
                        "#": {
                            "valid_children": ["Jobs"]
                        },
                        "Jobs": {
                            "valid_children": ["Packages"]
                        },
                        "Packages": {
                            "valid_children": ["Items"]
                        },
                        "Items": {
                            "valid_children": []
                        }
                    }
                });



(Note: The type names for both trees are still in flux, I took an earlier example and plan to modify the types to suit my needs.)

Can you please tell me how to do the following to just the right tree j2:

1) display checkbox to display only for the parent node level ('Home' and 'Work' in the above example)
2) user to be able to drag and drop at the same node level only within the right tree only

3) icing on the cake, some help with a trash can drag and drop event to remove nodes from the right tree j2 only (ie, not the left tree j1)

Thank you in advance for any assistance you can offer.

Regards,

- Charlie


Ivan Bozhanov

unread,
Dec 30, 2015, 2:08:53 PM12/30/15
to jsTree
Hi,

1) You can achieve that with CSS #your-tree .jstree-node .jstree-node .jstree-checkbox { display:none; } That will hide all checkboxes deeper than the first level

2) For this - use the check_callback function - you can detect if the dragged node is about to be dropped somewhere in its own parent and return true, otherwise - return false.

3) Use the move_node.jstree event and if the parent is the trash can - call delete_node

Best regards,
Ivan
Reply all
Reply to author
Forward
0 new messages