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;
}
<link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<div id="container">
<div id="boxA" class="box">
<h4>box A</h4>
<div id="A1" class="slot">
<div id="a1" class="item"></div>
</div>
<div id="A2" class="slot">
<div id="a2" class="item"></div>
</div>
<div id="A3" class="slot">
<div id="a3" class="item"></div>
</div>
<div id="A4" class="slot"></div>
<div id="A5" class="slot"></div>
</div>
<div id="boxB" class="box">
<h4>box B</h4>
<div id="B1" class="slot"></div>
<div id="B2" class="slot">
<div id="b2" class="item"></div>
</div>
<div id="B3" class="slot"></div>
<div id="B4" class="slot"></div>
<div id="B5" class="slot">
<div id="b5" class="item"></div>
</div>
</div>
</div>
Other references:
P.S: This will only work if the draggable is smaller than droppable (Which is true in this case)
If you mean, you want to drag and drop something and you want to revert if the data is dropped in the wrong area, then you can you use following code as a sample to achive your target
$(function() {
$(".connectedSortable").sortable({
connectWith: ".connectedSortable",
placeholder: "ui-state-highlight",
//containment: "parent",
revert: true
});
$("#sortable2").sortable({
connectWith: ".connectedSortable",
receive: function(event, ui) {
if (ui.item.attr('cust-attr') != 'm') {
console.log('wrong element');
$("#" + ui.sender.attr('id')).sortable('cancel');
}
}
});
$("#sortable2x").sortable({
connectWith: ".connectedSortable",
receive: function(event, ui) {
if (ui.item.attr('cust-attr') == 'm') {
console.log('wrong element');
$("#" + ui.sender.attr('id')).sortable('cancel');
}
}
});
});
#sortable1,
#sortable1x,
#sortable2,
#sortable2x {
list-style-type: none;
margin: 0;
padding: 0 0 2.5em;
float: left;
margin-right: 10px;
}
#sortable1 li,
#sortable1x li,
#sortable2 li,
#sortable2x li {
box-shadow: 2px 2px 0 #6D6D6D;
cursor: pointer;
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 150px;
}
#sortable2 .ui-selecting,
#sortable2x .ui-selecting {
background: #FECA40;
}
#sortable2 .ui-selected,
#sortable2x .ui-selected {
background: #F39814;
color: white;
}
#sortable1x,
#sortable2x {
list-style-type: none;
margin: 0;
width: 60%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<link href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css" rel="stylesheet">
<div style="width:600px;height:360px;">
<div style="float:left;">
Set 1 :
</div>
<div>
<ul id="sortable1" class="connectedSortable" style="border: 1px solid #000000;width:220px;height:300px;padding:4px;">
<li class="ui-state-default" cust-attr="m">Item 1 Set 1 X</li>
<li class="ui-state-default" cust-attr="m">Item 2 Set 1 X</li>
<li class="ui-state-default">Item 3 Set 1 X</li>
<li class="ui-state-default">Item 4 Set 1 X</li>
<li class="ui-state-default">Item 5 Set 1 X</li>
</ul>
<ul id="sortable1x" class="connectedSortable" style="border: 1px solid #000000;width:220px;height:300px;padding:4px;">
<li class="ui-state-default" cust-attr="m">Item 1 Set 1 Y</li>
<li class="ui-state-default" cust-attr="m">Item 2 Set 1 Y</li>
<li class="ui-state-default">Item 3 Set 1 Y</li>
<li class="ui-state-default">Item 4 Set 1 Y</li>
<li class="ui-state-default">Item 5 Set 1 Y</li>
</ul>
</div>
</div>
<div style="width:600px;height:360px;">
<div style="float:left;">
Set 2 :
</div>
<div>
<ul id="sortable2" class="connectedSortable connectedSortablex" style="border: 1px solid #000000;width:220px;height:300px;padding:4px;">
</ul>
<ul id="sortable2x" class="connectedSortable connectedSortablex" style="border: 1px solid #000000;width:220px;height:300px;padding:4px;">
</ul>
</div>
</div>
Click the below link to see demo http://jsfiddle.net/g90rau5p/3/
If you want multiple items drop, use multisort jquery library which can be used along with jqueryUI. For more details about it go to https://github.com/shvetsgroup/jquery.multisortable