MDL-34209 JavaScript: Simplify section drag/drop to fix reordering issues

This commit is contained in:
Andrew Nicols 2013-10-09 22:41:33 +08:00
parent 9844660858
commit 314cc22a28
2 changed files with 83 additions and 38 deletions

View file

@ -135,20 +135,37 @@ YUI.add('moodle-course-dragdrop', function(Y) {
this.drop_hit(e);
},
get_section_index: function(node) {
var sectionlistselector = '.' + CSS.COURSECONTENT + ' ' + M.course.format.get_section_selector(Y),
sectionList = Y.all(sectionlistselector),
nodeIndex = sectionList.indexOf(node),
zeroIndex = sectionList.indexOf(Y.one('#section-0'));
return (nodeIndex - zeroIndex);
},
drop_hit : function(e) {
var drag = e.drag;
// Get a reference to our drag node
var dragnode = drag.get('node');
var dropnode = e.drop.get('node');
// Prepare some variables
var dragnodeid = Number(this.get_section_id(dragnode));
var dropnodeid = Number(this.get_section_id(dropnode));
var loopstart = dragnodeid;
var loopend = dropnodeid;
// Get references to our nodes and their IDs.
var dragnode = drag.get('node'),
dragnodeid = this.get_section_id(dragnode),
loopstart = dragnodeid,
if (this.goingup) {
loopstart = dropnodeid;
dropnodeindex = this.get_section_index(dragnode),
loopend = dropnodeindex;
if (dragnodeid === dropnodeindex) {
Y.log("Skipping move - same location moving " + dragnodeid + " to " + dropnodeindex, 'debug', 'moodle-course-dragdrop');
return;
}
Y.log("Moving from position " + dragnodeid + " to position " + dropnodeindex, 'debug', 'moodle-course-dragdrop');
if (loopstart > loopend) {
// If we're going up, we need to swap the loop order
// because loops can't go backwards.
loopstart = dropnodeindex;
loopend = dragnodeid;
}
@ -173,7 +190,7 @@ YUI.add('moodle-course-dragdrop', function(Y) {
params['class'] = 'section';
params.field = 'move';
params.id = dragnodeid;
params.value = dropnodeid;
params.value = dropnodeindex;
// Do AJAX request
var uri = M.cfg.wwwroot + this.get('ajaxurl');
@ -196,27 +213,36 @@ YUI.add('moodle-course-dragdrop', function(Y) {
M.course.format.process_sections(Y, sectionlist, responsetext, loopstart, loopend);
} catch (e) {}
// Update all of the section IDs - first unset them, then set them
// to avoid duplicates in the DOM.
var index;
// Classic bubble sort algorithm is applied to the section
// nodes between original drag node location and the new one.
do {
var swapped = false;
for (var i = loopstart; i <= loopend; i++) {
if (this.get_section_id(sectionlist.item(i-1)) > this.get_section_id(sectionlist.item(i))) {
// Swap section id
var sectionid = sectionlist.item(i-1).get('id');
sectionlist.item(i-1).set('id', sectionlist.item(i).get('id'));
sectionlist.item(i).set('id', sectionid);
// See what format needs to swap
M.course.format.swap_sections(Y, i-1, i);
// Update flag
do {
swapped = false;
for (index = loopstart; index <= loopend; index++) {
if (this.get_section_id(sectionlist.item(index - 1)) >
this.get_section_id(sectionlist.item(index))) {
Y.log("Swapping " + this.get_section_id(sectionlist.item(index - 1)) +
" with " + this.get_section_id(sectionlist.item(index)));
// Swap section id.
var sectionid = sectionlist.item(index - 1).get('id');
sectionlist.item(index - 1).set('id', sectionlist.item(index).get('id'));
sectionlist.item(index).set('id', sectionid);
// See what format needs to swap.
M.course.format.swap_sections(Y, index - 1, index);
// Update flag.
swapped = true;
}
}
loopend = loopend - 1;
} while (swapped);
// Finally, hide the lightbox
window.setTimeout(function(e) {
window.setTimeout(function() {
lightbox.hide();
}, 250);
},

View file

@ -15,7 +15,7 @@ YUI.add('moodle-core-dragdrop', function(Y) {
Y.extend(DRAGDROP, Y.Base, {
goingup : null,
lasty : null,
absgoingup : null,
samenodeclass : null,
parentnodeclass : null,
groups : [],
@ -120,23 +120,38 @@ YUI.add('moodle-core-dragdrop', function(Y) {
},
global_drag_drag : function(e) {
var drag = e.target;
var drag = e.target,
info = e.info;
// Check that drag object belongs to correct group
if (!this.in_group(drag)) {
return;
}
//Get the last y point
var y = drag.lastXY[1];
//is it greater than the lasty var?
if (y < this.lasty) {
//We are going up
// Note, we test both < and > situations here. We don't want to
// effect a change in direction if the user is only moving side
// to side with no Y position change.
// Detect changes in the position relative to the start point.
if (info.start[1] < info.xy[1]) {
// We are going up if our final position is higher than our start position.
this.absgoingup = true;
} else if (info.start[1] > info.xy[1]) {
// Otherwise we're going down.
this.absgoingup = false;
}
// Detect changes in the position relative to the last movement.
if (info.delta[1] < 0) {
// We are going up if our final position is higher than our start position.
this.goingup = true;
} else {
//We are going down.
} else if (info.delta[1] > 0) {
// Otherwise we're going down.
this.goingup = false;
}
//Cache for next check
this.lasty = y;
this.drag_drag(e);
},
@ -152,13 +167,17 @@ YUI.add('moodle-core-dragdrop', function(Y) {
this.lastdroptarget = e.drop;
//Are we dropping on the same node?
if (drop.hasClass(this.samenodeclass)) {
//Are we not going up?
if (!this.goingup) {
drop = drop.next('.'+this.samenodeclass);
var where;
if (this.goingup) {
where = "before";
} else {
where = "after";
}
//Add the node
e.drop.get('node').ancestor().insertBefore(drag, drop);
} else if (drop.hasClass(this.parentnodeclass) && !drop.contains(drag)) {
} else if ((drop.hasClass(this.parentnodeclass) || drop.test('[data-droptarget="1"]')) && !drop.contains(drag)) {
// We are dropping on parent node and it is empty
if (this.goingup) {
drop.append(drag);