diff --git a/README.md b/README.md index 60caa87..a935ba4 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,16 @@ var sortable = new Sortable(el, { // Attempt to drag a filtered element onFilter: function (/**Event*/evt) { var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event. + }, + + // Event when you move an item in the list or between lists + onMove: function (/**Event*/evt) { + // Example: http://jsbin.com/tuyafe/1/edit?js,output + evt.dragged; // dragged HTMLElement + evt.draggedRect; // TextRectangle {left, top, right и bottom} + evt.related; // HTMLElement on which have guided + evt.relatedRect; // TextRectangle + // retrun false; — for cancel } }); ``` diff --git a/Sortable.js b/Sortable.js index 4527f6c..346887e 100644 --- a/Sortable.js +++ b/Sortable.js @@ -58,27 +58,6 @@ _silent = false, - _dispatchEvent = function (sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) { - var evt = document.createEvent('Event'), - options = (sortable || rootEl[expando]).options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - - evt.initEvent(name, true, true); - - evt.item = targetEl || rootEl; - evt.from = fromEl || rootEl; - evt.clone = cloneEl; - - evt.oldIndex = startIndex; - evt.newIndex = newIndex; - - if (options[onName]) { - options[onName].call(sortable, evt); - } - - rootEl.dispatchEvent(evt); - }, - abs = Math.abs, slice = [].slice, @@ -537,13 +516,13 @@ if (activeGroup && !options.disabled && (isOwner - ? canSort || (revert = !rootEl.contains(dragEl)) + ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list : activeGroup.pull && groupPut && ( (activeGroup.name === group.name) || // by Name (groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array ) ) && - (evt.rootEl === void 0 || evt.rootEl === this.el) + (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback ) { // Smart auto-scrolling _autoScroll(evt, options, this.el); @@ -582,9 +561,11 @@ _cloneHide(isOwner); - el.appendChild(dragEl); - this._animate(dragRect, dragEl); - target && this._animate(targetRect, target); + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect)) { + el.appendChild(dragEl); + this._animate(dragRect, dragEl); + target && this._animate(targetRect, target); + } } else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { if (lastEl !== target) { @@ -604,25 +585,27 @@ after ; - _silent = true; - setTimeout(_unsilent, 30); + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect)) { + _silent = true; + setTimeout(_unsilent, 30); - _cloneHide(isOwner); + _cloneHide(isOwner); - if (floating) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; - } else { - after = (nextSibling !== dragEl) && !isLong || halfway && isLong; - } + if (floating) { + after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; + } else { + after = (nextSibling !== dragEl) && !isLong || halfway && isLong; + } - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } - this._animate(dragRect, dragEl); - this._animate(targetRect, target); + this._animate(dragRect, dragEl); + this._animate(targetRect, target); + } } } }, @@ -986,6 +969,54 @@ } + + function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) { + var evt = document.createEvent('Event'), + options = (sortable || rootEl[expando]).options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + + evt.initEvent(name, true, true); + + evt.to = rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + + evt.oldIndex = startIndex; + evt.newIndex = newIndex; + + if (options[onName]) { + options[onName].call(sortable, evt); + } + + rootEl.dispatchEvent(evt); + } + + + function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; + + if (onMoveFn) { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + + retVal = onMoveFn.call(sortable, evt); + } + + return retVal !== false; + } + + function _disableDraggable(el) { el.draggable = false; }