MDL-65539 dragdrop: Allow direction detection when using keyboard

Before this change keyboard drag and drop could not detect the
direction of movement, this meant that an item would only be placed
below an item or at the top of a container item.

This change means that extending modules can declare
detectkeyboarddirection to true. This will mean that when an item is
moved it's position will be determined by the direction of travel as
it would be when dragging using the mouse.

If detectkeyboarddirection is true then:

* If you move an item upwards it will be placed before the item
  selected in the drop menu
* If you move a item downwards it will be placed after the item
  selected in the drop menu
* The item above the one being dragged will now be displayed on
  the drop menu

If detectkeyboarddirection is false there will be no change in
behaviour.
This commit is contained in:
Neill Magill 2019-05-09 16:10:16 +01:00
parent b5c9fb4a3d
commit 472c953093
4 changed files with 65 additions and 17 deletions

View File

@ -101,6 +101,15 @@ Y.extend(DRAGDROP, Y.Base, {
*/
lastdroptarget: null,
/**
* Should the direction of a keyboard drag and drop item be detected.
*
* @property detectkeyboarddirection
* @type Boolean
* @default false
*/
detectkeyboarddirection: false,
/**
* Listeners.
*
@ -420,7 +429,7 @@ Y.extend(DRAGDROP, Y.Base, {
var className = node.getAttribute("class").split(' ').join(', .');
if (node.drop && node.drop.inGroup(this.groups) && node.drop.get('node') !== dragcontainer &&
node.next(className) !== dragcontainer) {
!(node.next(className) === dragcontainer && !this.detectkeyboarddirection)) {
// This is a drag and drop target with the same class as the grabbed node.
validdrop = true;
} else {
@ -568,6 +577,16 @@ Y.extend(DRAGDROP, Y.Base, {
M.core.dragdrop.dropui.hide();
// Cancel the event.
e.preventDefault();
// Detect the direction of travel.
if (this.detectkeyboarddirection && dragcontainer.getY() > droptarget.getY()) {
// We can detect the keyboard direction and it is going up.
this.absgoingup = true;
this.goingup = true;
} else {
// The default behaviour is to treat everything as moving down.
this.absgoingup = false;
this.goingup = false;
}
// Convert to drag drop events.
var dragevent = new this.simulated_drag_drop_event(dragcontainer, dragcontainer);
var dropevent = new this.simulated_drag_drop_event(dragcontainer, droptarget);
@ -576,10 +595,7 @@ Y.extend(DRAGDROP, Y.Base, {
this.global_drop_over(dropevent);
if (droptarget.hasClass(this.parentnodeclass) && droptarget.contains(dragcontainer)) {
// The global_drop_over function does not handle the case where an item was moved up, without the
// 'goingup' variable being set, as is the case wih keyboard drag/drop. We must detect this case and
// apply it after the drop_over, but before the drop_hit event in order for it to be moved to the
// correct location.
// Handle the case where an item is dropped into a container (for example an activity into a new section).
droptarget.prepend(dragcontainer);
}

File diff suppressed because one or more lines are too long

View File

@ -101,6 +101,15 @@ Y.extend(DRAGDROP, Y.Base, {
*/
lastdroptarget: null,
/**
* Should the direction of a keyboard drag and drop item be detected.
*
* @property detectkeyboarddirection
* @type Boolean
* @default false
*/
detectkeyboarddirection: false,
/**
* Listeners.
*
@ -420,7 +429,7 @@ Y.extend(DRAGDROP, Y.Base, {
var className = node.getAttribute("class").split(' ').join(', .');
if (node.drop && node.drop.inGroup(this.groups) && node.drop.get('node') !== dragcontainer &&
node.next(className) !== dragcontainer) {
!(node.next(className) === dragcontainer && !this.detectkeyboarddirection)) {
// This is a drag and drop target with the same class as the grabbed node.
validdrop = true;
} else {
@ -568,6 +577,16 @@ Y.extend(DRAGDROP, Y.Base, {
M.core.dragdrop.dropui.hide();
// Cancel the event.
e.preventDefault();
// Detect the direction of travel.
if (this.detectkeyboarddirection && dragcontainer.getY() > droptarget.getY()) {
// We can detect the keyboard direction and it is going up.
this.absgoingup = true;
this.goingup = true;
} else {
// The default behaviour is to treat everything as moving down.
this.absgoingup = false;
this.goingup = false;
}
// Convert to drag drop events.
var dragevent = new this.simulated_drag_drop_event(dragcontainer, dragcontainer);
var dropevent = new this.simulated_drag_drop_event(dragcontainer, droptarget);
@ -576,10 +595,7 @@ Y.extend(DRAGDROP, Y.Base, {
this.global_drop_over(dropevent);
if (droptarget.hasClass(this.parentnodeclass) && droptarget.contains(dragcontainer)) {
// The global_drop_over function does not handle the case where an item was moved up, without the
// 'goingup' variable being set, as is the case wih keyboard drag/drop. We must detect this case and
// apply it after the drop_over, but before the drop_hit event in order for it to be moved to the
// correct location.
// Handle the case where an item is dropped into a container (for example an activity into a new section).
droptarget.prepend(dragcontainer);
}

View File

@ -99,6 +99,15 @@ Y.extend(DRAGDROP, Y.Base, {
*/
lastdroptarget: null,
/**
* Should the direction of a keyboard drag and drop item be detected.
*
* @property detectkeyboarddirection
* @type Boolean
* @default false
*/
detectkeyboarddirection: false,
/**
* Listeners.
*
@ -418,7 +427,7 @@ Y.extend(DRAGDROP, Y.Base, {
var className = node.getAttribute("class").split(' ').join(', .');
if (node.drop && node.drop.inGroup(this.groups) && node.drop.get('node') !== dragcontainer &&
node.next(className) !== dragcontainer) {
!(node.next(className) === dragcontainer && !this.detectkeyboarddirection)) {
// This is a drag and drop target with the same class as the grabbed node.
validdrop = true;
} else {
@ -566,6 +575,16 @@ Y.extend(DRAGDROP, Y.Base, {
M.core.dragdrop.dropui.hide();
// Cancel the event.
e.preventDefault();
// Detect the direction of travel.
if (this.detectkeyboarddirection && dragcontainer.getY() > droptarget.getY()) {
// We can detect the keyboard direction and it is going up.
this.absgoingup = true;
this.goingup = true;
} else {
// The default behaviour is to treat everything as moving down.
this.absgoingup = false;
this.goingup = false;
}
// Convert to drag drop events.
var dragevent = new this.simulated_drag_drop_event(dragcontainer, dragcontainer);
var dropevent = new this.simulated_drag_drop_event(dragcontainer, droptarget);
@ -574,10 +593,7 @@ Y.extend(DRAGDROP, Y.Base, {
this.global_drop_over(dropevent);
if (droptarget.hasClass(this.parentnodeclass) && droptarget.contains(dragcontainer)) {
// The global_drop_over function does not handle the case where an item was moved up, without the
// 'goingup' variable being set, as is the case wih keyboard drag/drop. We must detect this case and
// apply it after the drop_over, but before the drop_hit event in order for it to be moved to the
// correct location.
// Handle the case where an item is dropped into a container (for example an activity into a new section).
droptarget.prepend(dragcontainer);
}