views:

1187

answers:

3

I have a draggable with a custom helper. Sometimes the helper is a clone and sometimes it is the original element. The problem is that when the helper is the original element and is not dropped on a valid droppable it gets removed. My solution looks like this so far:

in my on_dropped callback I set ui.helper.dropped_on_droppable to true;

In the stop callback of the draggable, I check for that variable and then ... what do I do?

$('.my_draggable').draggable({
    stop   : function(e, ui) {
        if (!ui.helper.dropped_on_droppable) {
            /* what do I do here? */
        }
    },

Is this even the right approach?

A: 

I might be missing something here, but is it not simply a case of adding

revert: "invalid"

to the options of the draggable if the draggable is of an original element, not a clone?

Adam Hepton
No, jquery still automatically deletes the helper after reverting. I finally found a workaround at least....
MDCore
+1  A: 

Ok, I found a solution! It's ugly and it breaks the 'rules of encapsulation,' but at least it does the job.

Remember this is just for special cases! jQuery can handle its own helper removal just fine. In my case I had a helper that was sometimes the original element and sometimes a clone, so it wasn't always appropriate to delete the helper after reverting.

element.draggable({
    stop   : function(e, ui) {
        /* "dropped_on_droppable" is custom and set in my custom drop method
           ".moved_draggable" is custom and set in my custom drag method, 
                     to differentiate between the two types of draggables
        */               
        if (!ui.helper.dropped_on_droppable & ui.helper.hasClass('moved_draggable')) {
            /* this is the big hack that breaks encapsulation */
            $.ui.ddmanager.current.cancelHelperRemoval = true;
        }
    },

Warning: this breaks encapsulation and may not be forwards compatible

MDCore
A: 

I use a custom helper that aggregates multiple-selection draggables into a single div. This does not seem to jive with the revert functionality so I came up with this scheme. The elements are manually appended back to the original parent which I keep track of via .data().

.draggable({
    helper: function() {
     var div = $(document.createElement('div'))
      .data('lastParent', $(this).parent());
     return div;
    },
    start: function() {
     //... add multiple selection items to the helper..   
    },
    stop: function(event,ui) {
     $( $(ui.helper).data('lastParent') ).append( $(ui.helper).children() );
    }
}

This approach does lose out on the pretty animation, but it may be useful to you or someone else with this issue.