Reputation: 2685
I'm using jQueryUI
for draggable
and droppable
.
If I drop one element in droppable area and again if try to drop 2nd object. First dropped element should automatically remove and moved to draggable area.
Basically, only one element should be in droppable area.
As soon as droppable area has more than 1 element. It should just remove last element. If added one more element. Droppable area can't have more than 1 object.
code:
$("#dvSource img").draggable({
revert: "invalid",
//refreshPositions: true,
drag: function (event, ui) {
ui.helper.addClass("draggable");
},
stop: function (event, ui) {
ui.helper.removeClass("draggable");
if ($.ui.ddmanager.drop(ui.helper.data("draggable"), event)) {
console.log($("#dvDest img").length);
}
else {
//alert(image + " not dropped.");
}
}
});
$("#dvDest").droppable({
drop: function (event, ui) {
if ($("#dvDest img").length == 0) {
$("#dvDest").html("");
}
ui.draggable.addClass("dropped");
$("#dvDest").append(ui.draggable);
}
});
Upvotes: 1
Views: 1920
Reputation: 30903
I'm not fabulous with animations, but here is one way to do it.
Working Example: https://jsfiddle.net/Twisty/6auhhjxc/5/
jQuery
$(function() {
$("#dvSource img").draggable({
revert: "invalid",
drag: function(event, ui) {
ui.helper.addClass("draggable");
},
stop: function(event, ui) {
ui.helper.removeClass("draggable");
if ($.ui.ddmanager.drop(ui.helper.data("draggable"), event)) {
console.log($("#dvDest img").length);
}
}
});
$("#dvDest").droppable({
drop: function(event, ui) {
if ($("#dvDest img").length === 0) {
$("#dvDest").html("");
} else {
$("#dvDest img:first").hide(600, function() {
$(this).appendTo("#dvSource");
}).show(600);
}
ui.draggable.addClass("dropped");
$("#dvDest").append(ui.draggable);
}
});
});
In the drop, you already had a good check. So if there are img
elements in the destination when you drop
, You will want to append the drop and then append the first element back to the source.
I added some simple .hide()
and .show()
animations to make it fancy. I also adjusted each image, so you can see that the right item is moving back.
I suspect there is way to animate the the return in some fashion, that's just not in my bag of tricks. But this should get you there if that is in your bag.
Update after Comments
Working Example: https://jsfiddle.net/Twisty/6auhhjxc/7/
I found an issue in your draggable code that kept throwing an error. I removed it.
Since we destroy/create draggables over and over, I made a function to help do this. The drag/drop adds a bunch of styling to retain positioning so I drop that and the class
when I pass the img
back to the source.
jQuery
function makeDrag(el) {
// Pass me an object, and I will make it draggable
el.draggable({
revert: "invalid"
});
}
$(function() {
makeDrag($("#dvSource img"));
$("#dvDest").droppable({
drop: function(event, ui) {
if ($("#dvDest img").length === 0) {
$("#dvDest").html("");
} else {
$("#dvDest img:first").hide(600, function() {
$(this).removeAttr("class");
$(this).removeAttr("style");
$(this).appendTo("#dvSource");
}).show(600, function() {
makeDrag($(this));
});
}
ui.draggable.addClass("dropped");
ui.draggable.draggable("destroy");
$("#dvDest").append(ui.draggable);
}
});
});
The code in your stop
that was causing an issue:
if ($.ui.ddmanager.drop(ui.helper.data("draggable"), event)) {
console.log($("#dvDest img").length);
}
I switched to the uncompressed version, and the error thrown was:
TypeError: draggable is undefined
$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), ...
The section of code for this is:
$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
if ( !this.options ) {
return;
}
if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
dropped = this._drop.call( this, event ) || dropped;
}
if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
this.isout = true;
this.isover = false;
this._deactivate.call( this, event );
}
});
In the minimized code, this was t
, but the issue is the same. When you passed ui.helper.data("draggable")
to $.ui.ddmanager.drop()
, the value was null
or undefined
. The reason for this, in the scope of your script, was that ui.helper
did not have a data-draggable
attribute.
Again, it was not clear what the intended action was there, so I simply removed it.
Upvotes: 2