Hery
Hery

Reputation: 7639

Can a dojo.dnd.Source object contains another dojo.dnd.Source object as one of the child nodes?

I have looked at the this link for a tutorial on dojo drag and drop feature. But one thing I have noticed is that in all cases of the examples, the items to be dragged around are always a simple item, just a string object...

I need to create something like an item group where you can drag an item into the item group to append into the group and to drag the item group around as a whole.

Hence my question, is it possible to drag and drop a dojo.dnd.Source item into another dojo.dnd.Source item?

Upvotes: 1

Views: 559

Answers (2)

bstricks
bstricks

Reputation: 923

The problem is that when you start dragging and you drag over a Source of a child container, everything gets messed up. (Not exactly sure how). What you can do, is hide those child sources so that their overSource events never trigger:

1) Overrode the checkAcceptance function in Source.js. Just added the following for the if(!flag) return false;:

if(!flag){
    /**
     *  Main Source
     *  - Group 1
     *  -- Child 1
     *  -- Child 2
     *  - Group 2
     */
    var node = dojo.byId(this.node);    
// If the node being moved is the source, skip, but don't hide from view.
if('#'+dojo.attr(source.node, 'id') != '#'+dojo.attr(node, 'id')){
    // If the node being moved is an immediate child of the container, you can move it.
    if(dojo.query('#'+dojo.attr(source.node, 'id') + '>#'+dojo.attr(node, 'id')).length) {
        return true;                
    }

    // If this source is not a parent of the element, hide it.
    if(dojo.query('#'+dojo.attr(node, 'id') + ' #'+dojo.attr(source.node, 'id')).length == 0)
        dojo.addClass(node, 'hiddenSource');                
    }
    return false;
}

2) You need to also add the following as the first line under if(this.isDragging) in onMouseMove (important)

    var node = dojo.byId(this.node);

    // If this is immeditae child, drop it.
    if(dojo.query('#'+dojo.attr(m.source.node, 'id') + '>#'+dojo.attr(node, 'id')).length){
        m.canDrop(true);
            return;
    }

3) Extended onDndDrop to remove the added class to re display the hidden elements.

onDndDrop: function(source, nodes, copy, target)
{
    this.inherited(arguments);
    dojo.forEach(dojo.query('.hiddenSource'), 
        function(el){dojo.removeClass(el, 'hiddenSource');}
    );
}

4) Extend onDndCancel to do the above

onDndCanel: function()
{
    this.inherited(arguments);
    dojo.forEach(dojo.query('.hiddenSource'), 
        function(el){dojo.removeClass(el, 'hiddenSource');}
    );
}

This isn't the best solution since it hides the elements that can't be used with the current element that you are positioning, but it worked for me.

Upvotes: 0

Eugene Lazutkin
Eugene Lazutkin

Reputation: 43956

Short answer: no. Many people tried to patch it, but found more and more non-working edge cases, so those patches never made the Dojo proper.

If you truly need to show and manipulate a hierarchical data, consider a Tree Dijit.

Upvotes: 2

Related Questions