Drag from treeview, drop on div

17,755 views
Skip to first unread message

patri...@halsoftware.ie

unread,
Feb 14, 2014, 9:31:46 AM2/14/14
to jst...@googlegroups.com
Hi,

I need to be able to drag from a treeview and drop on div. The dragged item should only be copied from the treeview. I need to get a handle (name, id, etc) on the item dragged so I can fire appropriate event on the div. Is this functionality possible with jstree?, if so does anyone have any tips? All help appreciated.

Ivan Bozhanov

unread,
Feb 14, 2014, 10:03:36 AM2/14/14
to jst...@googlegroups.com
Listen on the document for the events dnd_move.vakata and dnd_stop.vakata. Here is an example:

    <div class="drag" style="padding:5px; display:inline-block; background:red; border-radius:4px;">Drag me</div>
    <div id="tree" class="jstree jstree-default"></div>
    <div class="drop" style="min-height:200px; min-width:200px; background:lime; border-radius:10px;">Drop here</div>

<script>
    $(function () {
        $('#tree').jstree({
            'plugins': [ 'dnd' ]
        });

        $('.drag')
            .on('mousedown', function (e) {
                return $.vakata.dnd.start(e, { 'jstree' : true, 'obj' : $(this), 'nodes' : [{ id : true, text: $(this).text() }] }, '<div id="jstree-dnd" class="jstree-default"><i class="jstree-icon jstree-er"></i>' + $(this).text() + '</div>');
            });
        $(document)
            .on('dnd_move.vakata', function (e, data) {
                var t = $(data.event.target);
                if(!t.closest('.jstree').length) {
                    if(t.closest('.drop').length) {
                        data.helper.find('.jstree-icon').removeClass('jstree-er').addClass('jstree-ok');
                    }
                    else {
                        data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
                    }
                }
            })
            .on('dnd_stop.vakata', function (e, data) {
                var t = $(data.event.target);
                if(!t.closest('.jstree').length) {
                    if(t.closest('.drop').length) {
                        $(data.element).clone().appendTo(t.closest('.drop'));
                        // node data:
                        // if(data.data.jstree && data.data.origin) { console.log(data.data.origin.get_node(data.element); }
                    }
                }
            });
  });
</script>

PAinVA

unread,
Feb 22, 2014, 5:58:02 PM2/22/14
to jst...@googlegroups.com
I have a similar problem in reverse.  I want to drag from a div onto the tree.

Is this div supposed to allow drag onto the tree?

<div class="drag" style="padding:5px; display:inline-block; background:red; border-radius:4px;">Drag me</div>

I tried that div with this tree.

I tried this

        $("#object-tree").jstree({
            'core'      : {"check_callback": true, 'data' : function (obj, cb) {cb.call(this,objects_tree_data)}},
            'plugins'   : ['dnd']
        })

When I drag the div onto a node on the tree I don't see a red X; i see a black circle with a angled line through it... any ideas?

Peter

João Marques

unread,
Feb 26, 2014, 3:14:51 PM2/26/14
to jst...@googlegroups.com
Ivan, 
This worked great on the desktop.
But on the iPad, I can drag the node out of the tree, I see the ok icon when hovering the '.drop' div, but nothing happens when I release my finger from the screen to dropping the node.
Tried Safari and Chrome.
Looks like "if (!t.closest('.jstree').length)" returns 1, thus not entering the if.
Any suggestion?

Ivan Bozhanov

unread,
Feb 27, 2014, 4:07:09 AM2/27/14
to jst...@googlegroups.com
I just added a fix for this in the repo and tested with IOS simulator - now it seems it is working. Thank you for reporting.

João Marques

unread,
Feb 27, 2014, 7:37:31 AM2/27/14
to jst...@googlegroups.com
It worked great Ivan! Thank you.
I can drop nodes in a div now using the iPad.
But what I'm really trying to accomplish here is to drop nodes into a select element.
Again, it works fine on the desktop, but not on the iPad. Tested Safari and Chrome.
I really don't now if it's a jquery/script limitation on mobile browsers or if your fix was made in a certain way that is preventing this to be done.
Any thoughts?

Ivan Bozhanov

unread,
Feb 27, 2014, 9:29:17 AM2/27/14
to jst...@googlegroups.com
No, I am not preventing anything ... maybe you should update the drop handler though, maybe something like:
$('<option value="">' + $(data.element).text() + '</option>').appendTo(t.closest('.drop'));
Because I doubt you will be able to append the DIV to a SELECT node. (the above code replaces: $(data.element).clone().appendTo(t.closest('.drop')); )
If that does not work it is something browser related.

Best regards,
Ivan

João Marques

unread,
Feb 27, 2014, 1:06:57 PM2/27/14
to jst...@googlegroups.com
I was not trying to append the DIV to a SELECT. I was creating <option> elements for each node dropped.
Anyway, I'm changing the select for another tree and will copy the nodes between them.

João Marques

unread,
Feb 27, 2014, 1:10:29 PM2/27/14
to jst...@googlegroups.com
B the way, it is actually moving the nodes between the trees.
Is there a way to copy the node and all their children toghether, if any?

João Marques

unread,
Feb 27, 2014, 1:31:50 PM2/27/14
to jst...@googlegroups.com
Nevermind. Got it from another thread. :)

PAinVA

unread,
Mar 19, 2014, 6:14:06 PM3/19/14
to jst...@googlegroups.com
FYI If you want the "hand mouse cursor" on foreign div hover add "jstree-ocl" to the classes too.  Like this:

<div class="drag jstree-ocl FO-sprite FO-soft" type="cSoft" id="cSoft">soft</div>

In my case FO-sprite and FO-soft are the same classes I use to get to my "types" icon (I want the foreign div to look the same).

This is how I pull the ID and type out of the div

        return $.vakata.dnd.start(  e, 
                                    { 'jstree' : true, 'obj' : $(this), 'nodes' : [{ id : true, text: $(this).text(), id : $(this).attr('id'), type : $(this).attr('type')}] }, 
                                    '<div id="jstree-dnd" class="jstree-default"><i class="jstree-icon jstree-er"></i>' + $(this).text() + '</div>');    

Peter

Knagi Reddy

unread,
Jul 2, 2014, 7:17:22 AM7/2/14
to jst...@googlegroups.com
In this code where should we create parent and child elements..like coustmor(parent node)nema,place(subnodes).and on drag and drop to another div it shoud show customer name,on drop of place it should should coustmor place...should be same as the screen provided..
thank you.
Untitled3.jpg

Ivan Bozhanov

unread,
Jul 2, 2014, 7:47:09 AM7/2/14
to jst...@googlegroups.com
As I said in the other topic - where is your code? What did you try and where did you fail? No one here provides coding services for free - just tell me what your problem is and I will help you resolve it, but you have to try yourself. As I said in the other topic - what you need has already been done and explained countless times - read this topic, read the docs, attempt to create what you need and share if you have any problems, show your code and I will help you find the problem but only after you have something ready, I will not code for you based on a specification - I try to help here in my spare time, do not abuse this!

Best regards,
Ivan
Message has been deleted

Nisham Mahsin

unread,
Aug 8, 2014, 12:59:01 PM8/8/14
to jst...@googlegroups.com

Thank you. you saved my day.

but some issues.
   i have several dropping div from single tree what i have done is ,
  i made several div with class="drop".
  it is working fine. but i dont want element to be dropped that are already dropped  in any div .
how to make this.

Ivan Bozhanov

unread,
Aug 9, 2014, 2:45:42 AM8/9/14
to jst...@googlegroups.com
There is a is_draggable collection - that is if you want to prevent the drag altogether (maintain an array of all IDs of dropped items and in is_draggable check if the node ID is in this array - if so - return false).
If you want to be able to drag those nodes, but to prevent the drop - in this check: if(t.closest('.drop').length) { add one more condition - check that the node ID is not in the array of dropped IDs (maintain it as in the previous step).

Best regards,
Ivan

Nisham Mahsin

unread,
Aug 10, 2014, 2:37:31 AM8/10/14
to jst...@googlegroups.com
 the purpose of several div is . they are selectable . after selecting divs it should merge to large size and removed already dropped element.
so the elements again becomes droppable .
so how to remove this items from the array?

Ivan Bozhanov

unread,
Aug 10, 2014, 3:33:29 AM8/10/14
to jst...@googlegroups.com
Sorry, but this is a very specific task. It is not something related to jstree I can help you with. Anyway - it seems pretty straightforward to maintain an array, jstree has absolutely nothing to do with this. Create a variable somewhere in scope (an array) and add and remove items to it as necessary - reacting to events like dropping, merging, etc.

Garci García

unread,
Aug 26, 2014, 4:31:03 AM8/26/14
to jst...@googlegroups.com
Hi

I'm trying this to drag and drop from jstree to a different <div>.
Is there a way to get the json data related for the selected node[s] on dropping event?

something like:


$(document)
            .on('dnd_move.vakata', function (e, data) {
                var t = $(data.event.target);
                //get here json data of the node!
                if(!t.closest('.jstree').length) {
                    if(t.closest('.drop').length) {
                        data.helper.find('.jstree-icon').removeClass('jstree-er').addClass('jstree-ok');
                    }
                    else {
                        data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
                    }
                }
            })
            .on('dnd_stop.vakata', function (e, data) {
                var t = $(data.event.target);
                if(!t.closest('.jstree').length) {
                    if(t.closest('.drop').length) {
                        //get here json data of the node!
                    }
                }
            });

Thanks for your time!

Ivan Bozhanov

unread,
Aug 26, 2014, 8:24:40 AM8/26/14
to jst...@googlegroups.com
Please read the approved answer carefully:


                        // node data:
                        // if(data.data.jstree && data.data.origin) { console.log(data.data.origin.get_node(data.element); }

Best regards,
Ivan

Garci García

unread,
Aug 28, 2014, 2:48:47 AM8/28/14
to jst...@googlegroups.com
Ok, need to change my lents!
Thanks!

Chienyi Cheri Hung

unread,
Nov 26, 2015, 10:51:33 AM11/26/15
to jsTree
I have the same question. How to do this in reverse? To drop into jstree from external divs, for example.

Thank you

Rodolphe Zerry

unread,
Nov 7, 2016, 3:09:45 AM11/7/16
to jsTree
Hi, I tried the code. It worked well except for the fact that the code keeps calling the function:
   .on('dnd_move.vakata.jstree', function (e, data) { ...}
after the customized function:
   .on('dnd_move.vakata.jstree', function (e, data) {  ... }
is called.
This has the effect of changing the icon back to a red cross because the code runs into:
data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');

I uncommented this line in the jstree.js file as a workaround. This fixed the problem. However, I am not sure if there is a better solution out there.
Thanks,
Rudy
    

Scott Deardorff

unread,
Apr 17, 2018, 6:48:34 PM4/17/18
to jsTree
I ran into the same issue and I'm stuck.  If I comment out the line, it seems to work. 

I'm using jstree 3.3.5

 The line is 6907 :
data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');

When I comment out the line it works.

My code for the callback looks like the following:

       $(document)
           .on('dnd_move.vakata', function (e, data) {
               var t = $(data.event.target);
               if(!t.closest('.jstree').length) {
                   if(t.closest('.drop').length) {

                       data.helper.find('.jstree-icon').removeClass('jstree-er').addClass('jstree-ok');
       
                   }
                   else {

                       data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
                   }
               }

           });

Scott Deardorff

unread,
Apr 17, 2018, 8:25:00 PM4/17/18
to jsTree
OK, I figured out the issue.  The line at 6907 is fired by the callback that starts at 6777

.on('dnd_move.vakata.jstree', function (e, data) {

If you load it at the end, just before the </body> tag, then it causes this error.  That's because the callback at 6777 fires  after the  custom dnd_move.vakata callback, so it resets your changes, removes the jstree-ok class and adds jstree-err.

In the case where you include jstree.min.js in the header, the built-in dnd_mov.vakata callback fires first, then the custom callback which does the right thing.  If you step through, you can see the built-in code first, switching the class to jstree-er, then when the custom callback code fires 

Hope this helps.

Nadja Kraemer

unread,
May 24, 2019, 9:32:23 AM5/24/19
to jsTree
Hey there, I just found your code and it works perfectly. However, when I drag an element into my div, it appears twice, so for example draggin "diagnoses" to my div results in "diagnoses diagnoses". 
I hope you still see this and can help me out!
Thanks in advance :)
Reply all
Reply to author
Forward
0 new messages