Reputation: 4653
I have a droppable div#space
and a collection of draggable li.element
. When I drag an li.element
in the div#space
a new ul.group
is created, the li.element
is appended to the ul.group
and finally the ul.group
is made droppable.
Given
I would like these elements to behave as follows:
li.element
is dropped in the ul.group
that does not contain it, the li.element
will be added to the ul.group
li.element
is dropped in the ul.group
that does contain it, the li.element
will be reverted to it's original positionli.element
is dropped in the div#space
(outside a ul.group
) an new group is created as mentioned above.The problem is that when an element is dropped on an ul.group
that does not accept it the parent div#space
will catch the event and will create a new group.
The ul.grpup
has an accept function that checks if the droppable is an element and if it's not already been dropped.
newULGroup.droppable({
drop: ...
accept: function(ui)
{
var isElement = ui.hasClass('element')
var elementId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(elementId).length > 0
return isElement && (!isAlreadyPresent)
},
greedy: true
});
How would you implement this behaviour if not by accepting everything and ignoring things in the drop handler? (I haven't tried but I guess that would work)
Edit
I patched the jquery-ui-1.8.4.js to pass the event to the accept function. Now I can stop the propagation with $(event).stopPropagation()
, but I have to animate manually the draggable helper back to its original position to simulate the revert, then remove it from the dom.
accept: function(ui, event)
{
var isCriteria = ui.hasClass('criteria')
var criteriaId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(criteriaId).length > 0
var accepted = isCriteria && (!isAlreadyPresent)
if (event && !accepted)
{
$(event.target).animate(ui.offset(), {complete: function() {$(this).remove()}})
$(event).stopPropagation()
}
return accepted
}
Unfortunately it seems to destroy the draggable behaviour from the original element as well. Why, oh why?
Upvotes: 1
Views: 2569
Reputation: 1106
I managed to achieve similar behavior, although using undocumented jQuery.ui feature.
If you look into the jquery.ui.draggable
implementation (at least for v1.8.16) the revert
option can also be a function. It has this
being the draggable element, single parameter which is the droppable who accepted the drop, and return value is a boolean
to indicate whether to revert the draggable or not.
So in your case you need to
div#space
and ul.group
always accept drops and be greedydrop
handler and processes item only if it's not in the group yetrevert
function and revert itself if it's already in the group.Upvotes: 1