/** * Kendo UI v2016.1.112 (http://www.telerik.com/kendo-ui) * Copyright 2016 Telerik AD. All rights reserved. * * Kendo UI commercial licenses may be obtained at * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete * If you do not own a commercial license, this file shall be governed by the trial license terms. */ (function (f, define) { define('kendo.sortable', ['kendo.draganddrop'], f); }(function () { var __meta__ = { id: 'sortable', name: 'Sortable', category: 'framework', depends: ['draganddrop'] }; (function ($, undefined) { var kendo = window.kendo, Widget = kendo.ui.Widget, START = 'start', BEFORE_MOVE = 'beforeMove', MOVE = 'move', END = 'end', CHANGE = 'change', CANCEL = 'cancel', ACTION_SORT = 'sort', ACTION_REMOVE = 'remove', ACTION_RECEIVE = 'receive', DEFAULT_FILTER = '>*', MISSING_INDEX = -1; function containsOrEqualTo(parent, child) { try { return $.contains(parent, child) || parent == child; } catch (e) { return false; } } function defaultHint(element) { return element.clone(); } function defaultPlaceholder(element) { return element.clone().removeAttr('id').css('visibility', 'hidden'); } var Sortable = Widget.extend({ init: function (element, options) { var that = this; Widget.fn.init.call(that, element, options); if (!that.options.placeholder) { that.options.placeholder = defaultPlaceholder; } if (!that.options.hint) { that.options.hint = defaultHint; } that.draggable = that._createDraggable(); }, events: [ START, BEFORE_MOVE, MOVE, END, CHANGE, CANCEL ], options: { name: 'Sortable', hint: null, placeholder: null, filter: DEFAULT_FILTER, holdToDrag: false, disabled: null, container: null, connectWith: null, handler: null, cursorOffset: null, axis: null, ignore: null, autoScroll: false, cursor: 'auto', moveOnDragEnter: false }, destroy: function () { this.draggable.destroy(); Widget.fn.destroy.call(this); }, _createDraggable: function () { var that = this, element = that.element, options = that.options; return new kendo.ui.Draggable(element, { filter: options.filter, hint: kendo.isFunction(options.hint) ? options.hint : $(options.hint), holdToDrag: options.holdToDrag, container: options.container ? $(options.container) : null, cursorOffset: options.cursorOffset, axis: options.axis, ignore: options.ignore, autoScroll: options.autoScroll, dragstart: $.proxy(that._dragstart, that), dragcancel: $.proxy(that._dragcancel, that), drag: $.proxy(that._drag, that), dragend: $.proxy(that._dragend, that) }); }, _dragstart: function (e) { var draggedElement = this.draggedElement = e.currentTarget, disabled = this.options.disabled, handler = this.options.handler, _placeholder = this.options.placeholder, placeholder = this.placeholder = kendo.isFunction(_placeholder) ? $(_placeholder.call(this, draggedElement)) : $(_placeholder); if (disabled && draggedElement.is(disabled)) { e.preventDefault(); } else if (handler && !$(e.initialTarget).is(handler)) { e.preventDefault(); } else { if (this.trigger(START, { item: draggedElement, draggableEvent: e })) { e.preventDefault(); } else { draggedElement.css('display', 'none'); draggedElement.before(placeholder); this._setCursor(); } } }, _dragcancel: function () { this._cancel(); this.trigger(CANCEL, { item: this.draggedElement }); this._resetCursor(); }, _drag: function (e) { var draggedElement = this.draggedElement, target = this._findTarget(e), targetCenter, cursorOffset = { left: e.x.location, top: e.y.location }, offsetDelta, axisDelta = { x: e.x.delta, y: e.y.delta }, direction, sibling, getSibling, axis = this.options.axis, moveOnDragEnter = this.options.moveOnDragEnter, eventData = { item: draggedElement, list: this, draggableEvent: e }; if (axis === 'x' || axis === 'y') { this._movementByAxis(axis, cursorOffset, axisDelta[axis], eventData); return; } if (target) { targetCenter = this._getElementCenter(target.element); offsetDelta = { left: Math.round(cursorOffset.left - targetCenter.left), top: Math.round(cursorOffset.top - targetCenter.top) }; $.extend(eventData, { target: target.element }); if (target.appendToBottom) { this._movePlaceholder(target, null, eventData); return; } if (target.appendAfterHidden) { this._movePlaceholder(target, 'next', eventData); } if (this._isFloating(target.element)) { if (axisDelta.x < 0 && (moveOnDragEnter || offsetDelta.left < 0)) { direction = 'prev'; } else if (axisDelta.x > 0 && (moveOnDragEnter || offsetDelta.left > 0)) { direction = 'next'; } } else { if (axisDelta.y < 0 && (moveOnDragEnter || offsetDelta.top < 0)) { direction = 'prev'; } else if (axisDelta.y > 0 && (moveOnDragEnter || offsetDelta.top > 0)) { direction = 'next'; } } if (direction) { getSibling = direction === 'prev' ? jQuery.fn.prev : jQuery.fn.next; sibling = getSibling.call(target.element); while (sibling.length && !sibling.is(':visible')) { sibling = getSibling.call(sibling); } if (sibling[0] != this.placeholder[0]) { this._movePlaceholder(target, direction, eventData); } } } }, _dragend: function (e) { var placeholder = this.placeholder, draggedElement = this.draggedElement, draggedIndex = this.indexOf(draggedElement), placeholderIndex = this.indexOf(placeholder), connectWith = this.options.connectWith, connectedList, isDefaultPrevented, eventData, connectedListEventData; this._resetCursor(); eventData = { action: ACTION_SORT, item: draggedElement, oldIndex: draggedIndex, newIndex: placeholderIndex, draggableEvent: e }; if (placeholderIndex >= 0) { isDefaultPrevented = this.trigger(END, eventData); } else { connectedList = placeholder.parents(connectWith).getKendoSortable(); eventData.action = ACTION_REMOVE; connectedListEventData = $.extend({}, eventData, { action: ACTION_RECEIVE, oldIndex: MISSING_INDEX, newIndex: connectedList.indexOf(placeholder) }); isDefaultPrevented = !(!this.trigger(END, eventData) && !connectedList.trigger(END, connectedListEventData)); } if (isDefaultPrevented || placeholderIndex === draggedIndex) { this._cancel(); return; } placeholder.replaceWith(draggedElement); draggedElement.show(); this.draggable.dropped = true; eventData = { action: this.indexOf(draggedElement) != MISSING_INDEX ? ACTION_SORT : ACTION_REMOVE, item: draggedElement, oldIndex: draggedIndex, newIndex: this.indexOf(draggedElement), draggableEvent: e }; this.trigger(CHANGE, eventData); if (connectedList) { connectedListEventData = $.extend({}, eventData, { action: ACTION_RECEIVE, oldIndex: MISSING_INDEX, newIndex: connectedList.indexOf(draggedElement) }); connectedList.trigger(CHANGE, connectedListEventData); } }, _findTarget: function (e) { var element = this._findElementUnderCursor(e), items, connectWith = this.options.connectWith, node; if ($.contains(this.element[0], element)) { items = this.items(); node = items.filter(element)[0] || items.has(element)[0]; return node ? { element: $(node), sortable: this } : null; } else if (this.element[0] == element && this._isEmpty()) { return { element: this.element, sortable: this, appendToBottom: true }; } else if (this.element[0] == element && this._isLastHidden()) { node = this.items().eq(0); return { element: node, sortable: this, appendAfterHidden: true }; } else if (connectWith) { return this._searchConnectedTargets(element, e); } }, _findElementUnderCursor: function (e) { var elementUnderCursor = kendo.elementUnderCursor(e), draggable = e.sender; if (containsOrEqualTo(draggable.hint[0], elementUnderCursor)) { draggable.hint.hide(); elementUnderCursor = kendo.elementUnderCursor(e); if (!elementUnderCursor) { elementUnderCursor = kendo.elementUnderCursor(e); } draggable.hint.show(); } return elementUnderCursor; }, _searchConnectedTargets: function (element, e) { var connected = $(this.options.connectWith), sortableInstance, items, node; for (var i = 0; i < connected.length; i++) { sortableInstance = connected.eq(i).getKendoSortable(); if ($.contains(connected[i], element)) { if (sortableInstance) { items = sortableInstance.items(); node = items.filter(element)[0] || items.has(element)[0]; if (node) { sortableInstance.placeholder = this.placeholder; return { element: $(node), sortable: sortableInstance }; } else { return null; } } } else if (connected[i] == element) { if (sortableInstance && sortableInstance._isEmpty()) { return { element: connected.eq(i), sortable: sortableInstance, appendToBottom: true }; } else if (this._isCursorAfterLast(sortableInstance, e)) { node = sortableInstance.items().last(); return { element: node, sortable: sortableInstance }; } } } }, _isCursorAfterLast: function (sortable, e) { var lastItem = sortable.items().last(), cursorOffset = { left: e.x.location, top: e.y.location }, lastItemOffset, delta; lastItemOffset = kendo.getOffset(lastItem); lastItemOffset.top += lastItem.outerHeight(); lastItemOffset.left += lastItem.outerWidth(); if (this._isFloating(lastItem)) { delta = lastItemOffset.left - cursorOffset.left; } else { delta = lastItemOffset.top - cursorOffset.top; } return delta < 0 ? true : false; }, _movementByAxis: function (axis, cursorOffset, delta, eventData) { var cursorPosition = axis === 'x' ? cursorOffset.left : cursorOffset.top, target = delta < 0 ? this.placeholder.prev() : this.placeholder.next(), targetCenter; if (target.length && !target.is(':visible')) { target = delta < 0 ? target.prev() : target.next(); } $.extend(eventData, { target: target }); targetCenter = this._getElementCenter(target); if (targetCenter) { targetCenter = axis === 'x' ? targetCenter.left : targetCenter.top; } if (target.length && delta < 0 && cursorPosition - targetCenter < 0) { this._movePlaceholder({ element: target, sortable: this }, 'prev', eventData); } else if (target.length && delta > 0 && cursorPosition - targetCenter > 0) { this._movePlaceholder({ element: target, sortable: this }, 'next', eventData); } }, _movePlaceholder: function (target, direction, eventData) { var placeholder = this.placeholder; if (!target.sortable.trigger(BEFORE_MOVE, eventData)) { if (!direction) { target.element.append(placeholder); } else if (direction === 'prev') { target.element.before(placeholder); } else if (direction === 'next') { target.element.after(placeholder); } target.sortable.trigger(MOVE, eventData); } }, _setCursor: function () { var cursor = this.options.cursor, body; if (cursor && cursor !== 'auto') { body = $(document.body); this._originalCursorType = body.css('cursor'); body.css({ 'cursor': cursor }); if (!this._cursorStylesheet) { this._cursorStylesheet = $(''); } this._cursorStylesheet.appendTo(body); } }, _resetCursor: function () { if (this._originalCursorType) { $(document.body).css('cursor', this._originalCursorType); this._originalCursorType = null; this._cursorStylesheet.remove(); } }, _getElementCenter: function (element) { var center = element.length ? kendo.getOffset(element) : null; if (center) { center.top += element.outerHeight() / 2; center.left += element.outerWidth() / 2; } return center; }, _isFloating: function (item) { return /left|right/.test(item.css('float')) || /inline|table-cell/.test(item.css('display')); }, _cancel: function () { this.draggedElement.show(); this.placeholder.remove(); }, _items: function () { var filter = this.options.filter, items; if (filter) { items = this.element.find(filter); } else { items = this.element.children(); } return items; }, indexOf: function (element) { var items = this._items(), placeholder = this.placeholder, draggedElement = this.draggedElement; if (placeholder && element[0] == placeholder[0]) { return items.not(draggedElement).index(element); } else { return items.not(placeholder).index(element); } }, items: function () { var placeholder = this.placeholder, items = this._items(); if (placeholder) { items = items.not(placeholder); } return items; }, _isEmpty: function () { return !this.items().length; }, _isLastHidden: function () { return this.items().length === 1 && this.items().is(':hidden'); } }); kendo.ui.plugin(Sortable); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); }));