Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery drag and drop - checking for a drop outside a droppable

My apologies if this was answered in another question, I could not find an answer specific to my problem!

I'm trying to test whether a jQuery draggable is being dropped outside of a legal droppable. This would normally be solved 90% of the time by reverting the draggable, but I don't want to do that. Instead, I want to do one thing if the draggable is dropped onto a droppable (working great!), and something else if it is dropped outside of all possible droppables (currently getting the better of me!).

In a nutshell:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    stop: function()
    {
        // need some way to check to see if this draggable has been dropped
        // successfully or not on an appropriate droppable...
        // I wish I could comment out my headache here like this too...
    }
});

I feel like I'm missing something really obvious...thanks in advance for any help!

like image 891
Chris Kempen Avatar asked Nov 11 '11 10:11

Chris Kempen


2 Answers

Because the droppable's drop event fires before the draggable's stop event, I think you can set a flag on the element being dragged in the drop event like so:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        ui.helper.data('dropped', true);
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    start: function(event, ui) {
        ui.helper.data('dropped', false);
    },
    stop: function(event, ui)
    {
        alert('stop: dropped=' + ui.helper.data('dropped'));
        // Check value of ui.helper.data('dropped') and handle accordingly...
    }
});
like image 78
Luke Girvin Avatar answered Oct 05 '22 15:10

Luke Girvin


I see that you already got an answer; anyway I had this same problem today and I solved it this way:

var outside = 0;

// this one control if the draggable is outside the droppable area
$('#droppable').droppable({
    accept      : '.draggable',
    out         : function(){
        outside = 1;
    },
    over        : function(){
        outside = 0;
    }
});

// this one control if the draggable is dropped
$('body').droppable({
    accept      : '.draggable',
    drop        : function(event, ui){
        if(outside == 1){
            alert('Dropped outside!');
        }else{
            alert('Dropped inside!');
        }
    }
});

I needed that because I couldn't change the options of my draggables, so I had to work only with droppables (I needed it inside the awesome FullCalendar plugin). I suppose it could have some issues using the "greedy" option of droppables, but it should work in most cases.

PS: sorry for my bad english.

EDIT: As suggested, I created the version using the jQuery.data; it can be found here : jsfiddle.net/Polmonite/WZma9/

Anyway jQuery.data documentation say:

Note that this method currently does not provide cross-platform support for setting data on XML documents, as Internet Explorer does not allow data to be attached via expando properties.

(meaning that it doesn't work on IE prior to 8)

EDIT 2: As noted by @Darin Peterson , the previous code doesn't work with more than one drop-area; this should fix that issue: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3: Example from EDIT 2 has a bug. If I drag "Drag me!" to the bottom droppable, then drop "Drag me too" to the upper droppable and then drop "Drag me too" outside, it alerts "Dropped inside!" So, don't use it.

EDIT 4: As noted by @Aleksey Gor, the example in Edit 2 was wrong; actually, it was more of an example to explain how to loop through all the draggables/droppables, but I actually forgot to remove the alert messages, so it was pretty confusing. Here the updated fiddle.

like image 24
Polmonite Avatar answered Oct 05 '22 14:10

Polmonite