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); 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) { drop_hit : function(e) {
var drag = e.drag; 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; // Get references to our nodes and their IDs.
var loopend = dropnodeid; var dragnode = drag.get('node'),
dragnodeid = this.get_section_id(dragnode),
loopstart = dragnodeid,
if (this.goingup) { dropnodeindex = this.get_section_index(dragnode),
loopstart = dropnodeid; 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; loopend = dragnodeid;
} }
@ -173,7 +190,7 @@ YUI.add('moodle-course-dragdrop', function(Y) {
params['class'] = 'section'; params['class'] = 'section';
params.field = 'move'; params.field = 'move';
params.id = dragnodeid; params.id = dragnodeid;
params.value = dropnodeid; params.value = dropnodeindex;
// Do AJAX request // Do AJAX request
var uri = M.cfg.wwwroot + this.get('ajaxurl'); 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); M.course.format.process_sections(Y, sectionlist, responsetext, loopstart, loopend);
} catch (e) {} } 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 // Classic bubble sort algorithm is applied to the section
// nodes between original drag node location and the new one. // nodes between original drag node location and the new one.
var swapped = false;
do { do {
var swapped = false; swapped = false;
for (var i = loopstart; i <= loopend; i++) { for (index = loopstart; index <= loopend; index++) {
if (this.get_section_id(sectionlist.item(i-1)) > this.get_section_id(sectionlist.item(i))) { if (this.get_section_id(sectionlist.item(index - 1)) >
// Swap section id this.get_section_id(sectionlist.item(index))) {
var sectionid = sectionlist.item(i-1).get('id'); Y.log("Swapping " + this.get_section_id(sectionlist.item(index - 1)) +
sectionlist.item(i-1).set('id', sectionlist.item(i).get('id')); " with " + this.get_section_id(sectionlist.item(index)));
sectionlist.item(i).set('id', sectionid); // Swap section id.
// See what format needs to swap var sectionid = sectionlist.item(index - 1).get('id');
M.course.format.swap_sections(Y, i-1, i); sectionlist.item(index - 1).set('id', sectionlist.item(index).get('id'));
// Update flag 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; swapped = true;
} }
} }
loopend = loopend - 1; loopend = loopend - 1;
} while (swapped); } while (swapped);
// Finally, hide the lightbox window.setTimeout(function() {
window.setTimeout(function(e) {
lightbox.hide(); lightbox.hide();
}, 250); }, 250);
}, },

View file

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