Skip to content

Commit a46c849

Browse files
committed
multidrag select across sortables
1 parent babf6ab commit a46c849

File tree

1 file changed

+71
-5
lines changed

1 file changed

+71
-5
lines changed

plugins/MultiDrag/MultiDrag.js

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
setRect,
1111
unsetRect,
1212
matrix,
13-
expando
13+
expando,
14+
getParentOrHost,
1415
} from '../../src/utils.js';
1516

1617
import dispatchEvent from '../../src/EventDispatcher.js';
@@ -19,6 +20,7 @@ let multiDragElements = [],
1920
multiDragClones = [],
2021
lastMultiDragSelect, // for selection with modifier key down (SHIFT)
2122
multiDragSortable,
23+
multiDragGroupMembers = {},
2224
initialFolding = false, // Initial multi-drag fold when drag started
2325
folding = false, // Folding any other time
2426
dragStarted = false,
@@ -44,6 +46,13 @@ function MultiDragPlugin() {
4446
}
4547
}
4648

49+
if (sortable.options.group) {
50+
if (multiDragGroupMembers[sortable.options.group.name] === undefined) {
51+
multiDragGroupMembers[sortable.options.group.name] = [];
52+
}
53+
multiDragGroupMembers[sortable.options.group.name].push(sortable);
54+
}
55+
4756
on(document, 'keydown', this._checkKeyDown);
4857
on(document, 'keyup', this._checkKeyUp);
4958

@@ -69,7 +78,6 @@ function MultiDragPlugin() {
6978
multiDragKeyDown: false,
7079
isMultiDrag: false,
7180

72-
7381
delayStartGlobal({ dragEl: dragged }) {
7482
dragEl = dragged;
7583
},
@@ -84,6 +92,7 @@ function MultiDragPlugin() {
8492
multiDragClones.push(clone(multiDragElements[i]));
8593

8694
multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
95+
multiDragClones[i].sortableParentEl = multiDragElements[i].sortableParentEl;
8796

8897
multiDragClones[i].draggable = false;
8998
multiDragClones[i].style['will-change'] = '';
@@ -141,6 +150,7 @@ function MultiDragPlugin() {
141150

142151
multiDragElements.forEach(multiDragElement => {
143152
multiDragElement.sortableIndex = index(multiDragElement);
153+
multiDragElement.sortableParentEl = getParentOrHost(multiDragElement);
144154
});
145155

146156
// Sort multi-drag elements
@@ -197,11 +207,46 @@ function MultiDragPlugin() {
197207
});
198208
},
199209

200-
dragOver({ target, completed, cancel }) {
210+
dragOver({ target, completed, cancel, originalEvent }) {
201211
if (folding && ~multiDragElements.indexOf(target)) {
202212
completed(false);
203213
cancel();
204214
}
215+
216+
const toSortable = target.parentNode[expando];
217+
218+
if (!toSortable || multiDragElements.length === 0) {
219+
return;
220+
}
221+
222+
let checkPut;
223+
224+
if (toSortable.options.group) {
225+
checkPut = toSortable.options.group.checkPut;
226+
}
227+
228+
const forbiddenMove = ~multiDragElements.findIndex((el) => {
229+
if (!el.sortableParentEl) {
230+
return false;
231+
}
232+
233+
const fromSortable = el.sortableParentEl[expando];
234+
235+
if (fromSortable && fromSortable.options.group && !fromSortable.options.group.checkPull(toSortable, fromSortable, el, originalEvent)) {
236+
return true;
237+
}
238+
239+
if (checkPut && !checkPut(toSortable, fromSortable, el, originalEvent)) {
240+
return true;
241+
}
242+
243+
return false;
244+
});
245+
246+
if (forbiddenMove) {
247+
completed(false);
248+
cancel();
249+
}
205250
},
206251

207252
revert({ fromSortable, rootEl, sortable, dragRect }) {
@@ -468,6 +513,15 @@ function MultiDragPlugin() {
468513

469514
off(document, 'keydown', this._checkKeyDown);
470515
off(document, 'keyup', this._checkKeyUp);
516+
517+
const groupMembers = multiDragGroupMembers[this.sortable.options.group];
518+
519+
if (groupMembers) {
520+
let membersIndex;
521+
if (~(membersIndex = groupMembers.indexOf(this.sortable))) {
522+
multiDragGroupMembers.splice(membersIndex, 1);
523+
}
524+
}
471525
},
472526

473527
_deselectMultiDrag(evt) {
@@ -476,8 +530,10 @@ function MultiDragPlugin() {
476530
// Only deselect if selection is in this sortable
477531
if (multiDragSortable !== this.sortable) return;
478532

479-
// Only deselect if target is not item in this sortable
480-
if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
533+
const groupSortables = findAllMembersInSortableGroup(this.sortable) || [this.sortable];
534+
535+
// Only deselect if target is not item in any sortable in group (including this)
536+
if (evt && ~groupSortables.findIndex((sortable) => closest(evt.target, this.options.draggable, sortable.el, false))) return;
481537

482538
// Only deselect if left click
483539
if (evt && evt.button !== 0) return;
@@ -546,6 +602,7 @@ function MultiDragPlugin() {
546602
multiDragElements.forEach(multiDragElement => {
547603
oldIndicies.push({
548604
multiDragElement,
605+
parentElement: multiDragElement.sortableParentEl,
549606
index: multiDragElement.sortableIndex
550607
});
551608

@@ -560,9 +617,11 @@ function MultiDragPlugin() {
560617
}
561618
newIndicies.push({
562619
multiDragElement,
620+
parentElement: multiDragElement.sortableParentEl,
563621
index: newIndex
564622
});
565623
});
624+
566625
return {
567626
items: [...multiDragElements],
568627
clones: [...multiDragClones],
@@ -618,4 +677,11 @@ function removeMultiDragElements() {
618677
});
619678
}
620679

680+
function findAllMembersInSortableGroup(sortable) {
681+
if (!sortable.options.group) {
682+
return null;
683+
}
684+
return multiDragGroupMembers[sortable.options.group.name] || [];
685+
}
686+
621687
export default MultiDragPlugin;

0 commit comments

Comments
 (0)