Commit de1f4a97 authored by Ludovic Kiefer's avatar Ludovic Kiefer Committed by Romain Courteaud

erp5_run_my_doc: reorder slides during drag and drop

parent 2b80b8a5
......@@ -495,6 +495,80 @@
]);
}
function recordSlidePosition(gadget) {
// [x,y] coordinates of the slides
gadget.slide_coordinate = [];
// store the data-slide-index of slides in the order we want to show them
// the key is the slide position into the list
// the value is the value of its data-slide-index converted to int
gadget.slide_order = [];
gadget.slide_order_start = []; //used to restore the slides positions
// Don't forget that the last element is the "add slide" button
var slide_list = gadget.element.querySelector("div.slide_list").children,
i,
coordinate;
for (i = 0; i < slide_list.length - 1; i += 1) {
coordinate = slide_list[i].getBoundingClientRect();
gadget.slide_coordinate[i] = [coordinate.x, coordinate.y];
gadget.slide_order[i] = i;
gadget.slide_order_start[i] = i;
}
}
function moveSlide(gadget, dragged_id, hovered_id) {
// dragged_id : data-slide-index of the dragged slide (Int)
// hovered_id : data-slide-index of the hovered slide (Int)
var slide_list = gadget.element.querySelector("div.slide_list").children,
j,
i,
dragged_index,
hovered_index,
moved,
slide,
pos_x,
pos_y;
// reset slides positions on dragend event
if (dragged_id === -1) {
for (j = 0; j < gadget.slide_order.length; j += 1) {
gadget.slide_order[j] = gadget.slide_order_start[j];
slide_list[j].style.left = "0";
slide_list[j].style.top = "0";
slide_list[j].style.position = "relative";
}
return;
}
// we move this slide (position in the list of slides)
dragged_index = gadget.slide_order.indexOf(dragged_id);
// over this slide (position in the list of slides)
hovered_index = gadget.slide_order.indexOf(hovered_id);
// drop the moved slide from the list
moved = gadget.slide_order.splice(dragged_index, 1);
// insert the moved slide on the right position into the list
gadget.slide_order.splice(hovered_index, 0, moved[0]);
// where to drop the slide (on drop event)
gadget.hovered_slide = hovered_index.toString();
for (i = 0; i < gadget.slide_order.length; i += 1) {
// Find slide that should be shown at that index
slide = slide_list[gadget.slide_order[i]];
//displace the slide at this relative position (CSS only, DOM unchanged)
pos_x = gadget.slide_coordinate[
gadget.slide_order[i]
][0];
pos_y = gadget.slide_coordinate[
gadget.slide_order[i]
][1];
slide.style.left = (gadget.slide_coordinate[i][0] -
pos_x).toString() + "px";
slide.style.top = (gadget.slide_coordinate[i][1] -
pos_y).toString() + "px";
slide.style.position = "relative";
}
}
///////////////////////////////////////////////////
// Gadget
///////////////////////////////////////////////////
......@@ -727,29 +801,32 @@
// Drag / drop management
///////////////////////////////////////////////////
.onEvent("dragstart", function (evt) {
var tag_name = evt.target.tagName;
if (tag_name !== 'SECTION') {
var closest_section = evt.target.closest('section'),
gadget = this;
if (closest_section === null) {
return;
}
// Store index of the dragged slide
evt.target.classList.add('drag');
recordSlidePosition(this);
// Store index of the dragged slide
evt.dataTransfer.effectAllowed = 'move';
evt.dataTransfer.setData('application/x-dragged-slide',
evt.target.getAttribute('data-slide-index'));
gadget.dragged_slide = evt.target.getAttribute('data-slide-index');
}, false, false)
.onEvent("dragend", function (evt) {
var tag_name = evt.target.tagName;
if (tag_name !== 'SECTION') {
moveSlide(this, -1, -1);
var closest_section = evt.target.closest('section');
if (closest_section === null) {
return;
}
evt.target.classList.remove('drag');
}, false, false)
.onEvent("dragover", function (evt) {
var tag_name = evt.target.tagName;
if (tag_name !== 'SECTION') {
var closest_section = evt.target.closest('section');
if (closest_section === null) {
return;
}
if (evt.preventDefault) {
......@@ -759,29 +836,47 @@
}, false, false)
.onEvent("dragenter", function (evt) {
var tag_name = evt.target.tagName;
if (tag_name !== 'SECTION') {
var closest_section = evt.target.closest('section'),
gadget,
dragged,
hovered;
if (closest_section === null) {
return;
}
// Provide a visual feedback to the user
// Showing where the slide can be dropped
if (evt.target.getAttribute('data-slide-index')) {
evt.target.classList.add('over');
gadget = this;
dragged = gadget.dragged_slide;
hovered = closest_section.getAttribute('data-slide-index');
if (dragged !== hovered) {
if (closest_section.getAttribute('data-slide-index')) {
moveSlide(this, parseInt(dragged, 10), parseInt(hovered, 10));
}
}
}, false, false)
.onEvent("dragleave", function (evt) {
var tag_name = evt.target.tagName;
if (tag_name !== 'SECTION') {
return;
//exits if mouse is indirectly over a section
if (evt.relatedTarget) {
var closest_section = evt.relatedTarget.closest('section'),
closest_slidelist;
if (closest_section !== null) {
return;
}
closest_slidelist = evt.relatedTarget.closest('div.slide_list');
if (closest_slidelist === null) {
// We are no longer over the slides, reset slide's positions
moveSlide(this, -1, -1);
}
}
evt.target.classList.remove('over');
}, false, false)
.onEvent("drop", function (evt) {
var gadget = this,
tag_name = evt.target.tagName,
tag_name = evt.target.closest('section').tagName,
slide_list,
source_index,
destination_index;
......@@ -794,17 +889,15 @@
evt.preventDefault(); // Necessary. Allows us to drop.
}
// Remove the over class
evt.target.classList.remove('over');
source_index = evt.dataTransfer.getData('application/x-dragged-slide');
if (source_index && evt.target.getAttribute('data-slide-index')) {
if (source_index && gadget.hovered_slide) {
source_index = parseInt(
source_index,
10
);
destination_index = parseInt(
evt.target.getAttribute('data-slide-index'),
gadget.hovered_slide,
10
);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment