Drawing a box with cursor (lasso) will select multiple .item
in this JSFiddle example.
Selected .item
's become draggable. Empty .slot
without an .item
inside is a valid droppable.
When you drop multiple draggables on multiple droppables, only the .item
which mouse is on will revert if its corresponding droppable not valid.
How to make every draggable revert if it's dropped on invalid droppable?
Javascript:
$(function () {
// we are going to store the selected objects in here
var selected = $([]),
total = [],
offset = {
top: 0,
left: 0
};
$(document).selectable({
filter: ".item",
start: function (event, ui) { //remove draggable from selection, otherwise previous selection will still be draggable.
$(total).draggable("destroy");
},
selected: function (event, ui) { // push selected into total[].
total.push(ui.selected)
},
unselected: function (event, ui) { //console.log('unselect ui: ',ui)
u = ui.unselected
//remove unselected from selection[].
total = jQuery.grep(total, function (n) {
return n !== u
});
//console.log('total array (unselected): ',total)
},
stop: function (vent, ui) {
//remove duplicated element from total[].
jQuery.unique(total)
$(total).each(function () {
$(this).draggable(dragOption)
})
//$(total).draggable(dragOption);
//var widget = $( ".selector" ).draggable( "widget" );
//console.log('widget: ',widget)
console.log('break line---------------------------- ')
}
});
//save drag option as an Obj.
dragOption = {
opacity: 0.45,
delay: 300,
connectToSortable: ".slot"
//,helper: "clone"
,
distance: 5,
snap: ".slot",
snapMode: "inner",
revert: "invalid",
start: function (event, ui) {
console.log('draggable start ui: ', ui)
selected = $(total).each(function () {
var el = $(this);
el.data("offset", el.offset())
});
offset = $(this).offset(); //get coordinates relative to document
},
drag: function (event, ui) { //console.log(offset.top)
var dt = ui.position.top - offset.top,
dl = ui.position.left - offset.left;
selected.not(this).each(function () {
// create the variable for we don't need to keep calling $("this")
// el = current element we are on
// off = what position was this element at when it was selected, before drag
var el = $(this),
off = el.data("offset");
el.css({
top: off.top + dt,
left: off.left + dl
});
});
},
stop: function (event, ui) {
console.log('drag stop ui : ', ui)
}
};
//save drop option as an Obj.
dropOption = {
accept: '.item',
drop: function (event, ui) {
console.log('drop event : ', event);
console.log('drop ui : ', ui)
},
activate: function (event, ui) { //console.log('this : ',this,'\n ui : ',ui)
},
out: function (event, ui) { //console.log('out',$(this))
},
deactivate: function (event, ui) { //console.log('deactivate')
},
tolerance: "intersect",
instance: function (event, ui) { //console.log('instance ui : ',ui)
},
over: function (event, ui) { //console.log('this item : ',ui.draggable[0],'on this slot: ',this)
},
activeClass: "green3"
}
// make empty slot droppable
$(".slot:not(:has(>div))").droppable(dropOption)
}) <!--doc ready-->
HTML:
<body>
<div id="container">
<div id="header"></div>
<div class="box" id="boxA">
<h4>box A</h4>
<div class="slot" id="A1">
<div class="item" id="a1"></div>
</div>
<div class="slot" id="A2">
<div class="item" id="a2"></div>
</div>
<div class="slot" id="A3">
<div class="item" id="a3"></div>
</div>
<div class="slot" id="A4"></div>
<div class="slot" id="A5"></div>
</div>
<div class ="box" id="boxB">
<h4>box B</h4>
<div class="slot" id="B1"></div>
<div class="slot" id="B2">
<div class="item" id="b2"></div>
</div>
<div class="slot" id="B3"></div>
<div class="slot" id="B4"></div>
<div class="slot" id="B5">
<div class="item" id="b5"></div>
</div>
</div>
</div>
</body>
CSS:
document {
background-color: #FFF;
}
.box {
height: 180px;
float: left;
border-top-width: 5px;
border-right-width: 5px;
border-bottom-width: 5px;
border-left-width: 5px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-top-color: #999;
border-right-color: #999;
border-bottom-color: #999;
border-left-color: #999;
width: 150px;
text-align: center;
margin-left: 100px;
}
.item {
position: absolute;
font-size: 12px;
height: 14px;
background-color: #CCC;
width: 110px;
text-decoration: none;
font-family: Arial, Helvetica, sans-serif;
color: #999;
margin-left: 6px;
text-align: center;
}
#header, #footer {
float: left;
height: 200px;
width: 100%;
}
.slot{
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: dotted;
border-right-style: dotted;
border-bottom-style: dotted;
border-left-style: dotted;
height: 15px;
width: 120px;
margin-top: 2px;
text-align: center;
vertical-align: middle;
line-height: 90px;
margin-right: auto;
margin-left: auto;
}
.ui-selecting {
background: #FECA40;
}
.ui-selected {
background-color: #F90;
}
.green3 {
background-color: #D9FFE2;
}