From 7bf48f580543eb7cd32e33000ac2c1d455fe4556 Mon Sep 17 00:00:00 2001 From: Dan Dascalescu Date: Sun, 7 Dec 2014 22:22:03 -0800 Subject: [PATCH] Expose old & new element index on drag&drop Fix #148 --- README.md | 38 ++++++++++++++++++++++++-------------- Sortable.js | 28 ++++++++++++++++++---------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7ce3fb5a6..9c27680f8 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ You can use any element for the list and its elements, not just `ul`/`li`. Here ### Options ```js var sortable = new Sortable(el, { - group: "name", // or { name: "..", pull: [true, false, clone], put: [true, false, array] } + group: "name", // or { name: "...", pull: [true, false, clone], put: [true, false, array] } sort: true, // sorting inside list disabled: false, // Disables the sortable if set to true. store: null, // @see Store @@ -52,32 +52,42 @@ var sortable = new Sortable(el, { dataTransfer.setData('Text', dragEl.textContent); }, - onStart: function (/*Event*/evt) { /* dragging started*/ }, - onEnd: function (/*Event*/evt) { /* dragging ended */ }, + // dragging started + onStart: function (/**Event*/evt) { + evt.oldIndex; // element index within parent + }, + + // dragging ended + onEnd: function (/**Event*/evt) { + evt.oldIndex; // element's old index within parent + evt.newIndex; // element's new index within parent + }, // Element is dropped into the list from another list - onAdd: function (/*Event*/evt){ - var itemEl = evt.item; // dragged HTMLElement - itemEl.from; // previous list + onAdd: function (/**Event*/evt) { + var itemEl = evt.item; // dragged HTMLElement + itemEl.from; // previous list + // + indexes from onEnd }, // Changed sorting within list - onUpdate: function (/*Event*/evt){ - var itemEl = evt.item; // dragged HTMLElement + onUpdate: function (/**Event*/evt) { + var itemEl = evt.item; // dragged HTMLElement + // + indexes from onEnd }, // Called by any change to the list (add / update / remove) - onSort: function (/*Event*/evt){ - var itemEl = evt.item; // dragged HTMLElement + onSort: function (/**Event*/evt) { + // same properties as onUpdate }, // Element is removed from the list into another list - onRemove: function (/*Event*/evt){ - var itemEl = evt.item; // dragged HTMLElement + onRemove: function (/**Event*/evt) { + // same properties as onUpdate }, - onFilter: function (/*Event*/evt){ - var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event. + onFilter: function (/**Event*/evt) { + var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event. } }); ``` diff --git a/Sortable.js b/Sortable.js index 694ea1f0f..da3cbb3eb 100644 --- a/Sortable.js +++ b/Sortable.js @@ -25,6 +25,7 @@ "use strict"; var dragEl, + startIndex, ghostEl, cloneEl, rootEl, @@ -47,12 +48,14 @@ _silent = false, - _dispatchEvent = function (rootEl, name, targetEl, fromEl) { + _dispatchEvent = function (rootEl, name, targetEl, fromEl, startIndex, newIndex) { var evt = document.createEvent('Event'); evt.initEvent(name, true, true); evt.item = targetEl || rootEl; evt.from = fromEl || rootEl; + if (startIndex !== undefined) evt.oldIndex = startIndex; + if (newIndex !== undefined) evt.newIndex = newIndex; rootEl.dispatchEvent(evt); }, @@ -163,6 +166,8 @@ el = this.el, filter = options.filter; + // get the index of the dragged element within its parent + startIndex = 0; var e = target; while (e = e.previousElementSibling) ++startIndex; if (evt.type === 'mousedown' && evt.button !== 0 || options.disabled) { return; // only left button or enabled @@ -245,7 +250,7 @@ } - _dispatchEvent(dragEl, 'start'); + _dispatchEvent(dragEl, 'start', undefined, undefined, startIndex); if (activeGroup.pull == 'clone') { @@ -502,28 +507,31 @@ ghostEl && ghostEl.parentNode.removeChild(ghostEl); if (dragEl) { + // get the index of the dragged element within its parent + var newIndex = 0, e = dragEl; while (e = e.previousElementSibling) ++newIndex; _disableDraggable(dragEl); _toggleClass(dragEl, this.options.ghostClass, false); if (!rootEl.contains(dragEl)) { - _dispatchEvent(dragEl, 'sort', dragEl, dragEl.parentNode); - _dispatchEvent(rootEl, 'sort', dragEl); + // drag from one list and drop into another + _dispatchEvent(dragEl, 'sort', dragEl, dragEl.parentNode, startIndex, newIndex); + _dispatchEvent(rootEl, 'sort', dragEl, undefined, startIndex, newIndex); // Add event - _dispatchEvent(dragEl, 'add', dragEl, rootEl); + _dispatchEvent(dragEl, 'add', dragEl, rootEl, startIndex, newIndex); // Remove event - _dispatchEvent(rootEl, 'remove', dragEl); + _dispatchEvent(rootEl, 'remove', dragEl, undefined, startIndex, newIndex); } else if (dragEl.nextSibling !== nextEl) { - // Update event - _dispatchEvent(dragEl, 'update'); - _dispatchEvent(dragEl, 'sort'); + // drag & drop within the same list + _dispatchEvent(dragEl, 'update', undefined, undefined, startIndex, newIndex); + _dispatchEvent(dragEl, 'sort', undefined, undefined, startIndex, newIndex); cloneEl && cloneEl.parentNode.removeChild(cloneEl); } - _dispatchEvent(rootEl, 'end'); + _dispatchEvent(rootEl, 'end', undefined, undefined, startIndex, newIndex); } // Set NULL