Drawing a box with cursor (lasso) will select multiple .item in this JSFiddle example.
Selected .item\'s become draggable. Empty .slo
You can make use of document.elementFromPoint.
For dropping/reverting the original draggable, we do the following once it is dropped in drop event:
.item or not in the dropevent.
If the droppable doesn't already contain an .item, Go to step 2, else go to step3.slot after resetting the positioning using css()For dropping/reverting the extra items being dragged:
We find the elements on the left and right visible area of each item being dragged (1px far from the element being dragged, Which is supposed to be the drop targets) usingdocument.elementFromPoint.
Since no actual drop event is triggered for these elements, we make use of the stop event of draggable to check whether either of the target's is a .slot
If either of them is a .slot, which means the item was dropped over a
droppable, we proceed to step1 mentioned above, else we go to step3
(manually revert the item to it's original position)
$(function() {
var dragOption = {
delay: 10,
distance: 5,
opacity: 0.45,
revert: "invalid",
revertDuration: 100,
start: function(event, ui) {
$(".ui-selected").each(function() {
$(this).data("original", $(this).position());
});
},
drag: function(event, ui) {
var offset = ui.position;
$(".ui-selected").not(this).each(function() {
var current = $(this).offset(),
targetLeft = document.elementFromPoint(current.left - 1, current.top),
targetRight = document.elementFromPoint(current.left + $(this).width() + 1, current.top);
$(this).css({
position: "relative",
left: offset.left,
top: offset.top
}).data("target", $.unique([targetLeft, targetRight]));
});
},
stop: function(event, ui) {
$(".ui-selected").not(this).each(function() {
var $target = $($(this).data("target")).filter(function(i, elm) {
return $(this).is(".slot") && !$(this).has(".item").length;
});
if ($target.length) {
$target.append($(this).css({
top: 0,
left: 0
}))
} else {
$(this).animate({
top: 0,
left: 0
}, "slow");
}
});
$(".ui-selected").data("original", null)
.data("target", null)
.removeClass("ui-selected");
}
},
dropOption = {
accept: '.item',
activeClass: "green3",
drop: function(event, ui) {
if ($(this).is(".slot") && !$(this).has(".item").length) {
$(this).append(ui.draggable.css({
top: 0,
left: 0
}));
} else {
ui.draggable.animate({
top: 0,
left: 0
}, 50);
}
}
}
$(".box").selectable({
filter: ".item",
start: function(event, ui) {
$(".ui-draggable").draggable("destroy");
},
stop: function(event, ui) {
$(".ui-selected").draggable(dragOption)
}
});
$(".slot").droppable(dropOption);
});
.box {
float: left;
width: 150px;
height: 180px;
text-align: center;
margin-left: 20px;
border: 5px solid #999;
}
.slot {
position: relative;
width: 120px;
height: 15px;
margin-top: 2px;
margin: 0 auto;
border: 1px dotted;
}
.item {
width: 110px;
height: 14px;
margin: 0 auto;
z-index: 1;
background-color: #CCC;
}
.ui-selecting {
background: #FECA40;
}
.ui-selected {
background-color: #F90;
}
.green3 {
background-color: #D9FFE2;
}
box A
box B
Other references:
P.S: This will only work if the draggable is smaller than droppable (Which is true in this case)