From c94fb32c7a3c28b18a27460aa2447eeec1fac1de Mon Sep 17 00:00:00 2001 From: Pascal Szewczyk Date: Mon, 18 Jul 2016 23:23:54 +0200 Subject: uikit added --- js/components/nestable.js | 653 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 653 insertions(+) create mode 100755 js/components/nestable.js (limited to 'js/components/nestable.js') diff --git a/js/components/nestable.js b/js/components/nestable.js new file mode 100755 index 0000000..573345d --- /dev/null +++ b/js/components/nestable.js @@ -0,0 +1,653 @@ +/*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ +/* + * Based on Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/ + */ +(function(addon) { + + var component; + + if (window.UIkit) { + component = addon(UIkit); + } + + if (typeof define == "function" && define.amd) { + define("uikit-nestable", ["uikit"], function(){ + return component || addon(UIkit); + }); + } + +})(function(UI) { + + "use strict"; + + var hasTouch = 'ontouchstart' in window, + html = UI.$html, + touchedlists = [], + $win = UI.$win, + draggingElement; + + var eStart = hasTouch ? 'touchstart' : 'mousedown', + eMove = hasTouch ? 'touchmove' : 'mousemove', + eEnd = hasTouch ? 'touchend' : 'mouseup', + eCancel = hasTouch ? 'touchcancel' : 'mouseup'; + + + UI.component('nestable', { + + defaults: { + listBaseClass : 'uk-nestable', + listClass : 'uk-nestable-list', + listItemClass : 'uk-nestable-item', + dragClass : 'uk-nestable-dragged', + movingClass : 'uk-nestable-moving', + noChildrenClass : 'uk-nestable-nochildren', + emptyClass : 'uk-nestable-empty', + handleClass : '', + collapsedClass : 'uk-collapsed', + placeholderClass: 'uk-nestable-placeholder', + noDragClass : 'uk-nestable-nodrag', + group : false, + maxDepth : 10, + threshold : 20, + idlethreshold : 10, + }, + + boot: function() { + + // adjust document scrolling + UI.$html.on('mousemove touchmove', function(e) { + + if (draggingElement) { + + var top = draggingElement.offset().top; + + if (top < UI.$win.scrollTop()) { + UI.$win.scrollTop(UI.$win.scrollTop() - Math.ceil(draggingElement.height()/2)); + } else if ( (top + draggingElement.height()) > (window.innerHeight + UI.$win.scrollTop()) ) { + UI.$win.scrollTop(UI.$win.scrollTop() + Math.ceil(draggingElement.height()/2)); + } + } + }); + + // init code + UI.ready(function(context) { + + UI.$("[data-uk-nestable]", context).each(function(){ + + var ele = UI.$(this); + + if (!ele.data("nestable")) { + UI.nestable(ele, UI.Utils.options(ele.attr("data-uk-nestable"))); + } + }); + }); + }, + + init: function() { + + var $this = this; + + Object.keys(this.options).forEach(function(key){ + + if(String(key).indexOf('Class')!=-1) { + $this.options['_'+key] = '.' + $this.options[key]; + } + }); + + this.find(this.options._listItemClass).find(">ul").addClass(this.options.listClass); + + this.checkEmptyList(); + + this.reset(); + this.element.data('nestable-group', this.options.group || UI.Utils.uid('nestable-group')); + + this.find(this.options._listItemClass).each(function() { + $this.setParent(UI.$(this)); + }); + + this.on('click', '[data-nestable-action]', function(e) { + + if ($this.dragEl || (!hasTouch && e.button !== 0)) { + return; + } + + e.preventDefault(); + + var target = UI.$(e.currentTarget), + action = target.data('nestableAction'), + item = target.closest($this.options._listItemClass); + + if (action === 'collapse') { + $this.collapseItem(item); + } + if (action === 'expand') { + $this.expandItem(item); + } + if (action === 'toggle') { + $this.toggleItem(item); + } + }); + + var onStartEvent = function(e) { + + var handle = UI.$(e.target), + link = handle.is('a[href]') ? handle:handle.parents('a[href]'); + + if (e.target === $this.element[0]) { + return; + } + + if (handle.is($this.options._noDragClass) || handle.closest($this.options._noDragClass).length) { + return; + } + + if (handle.is('[data-nestable-action]') || handle.closest('[data-nestable-action]').length) { + return; + } + + if ($this.options.handleClass && !handle.hasClass($this.options.handleClass)) { + + if ($this.options.handleClass) { + handle = handle.closest($this.options._handleClass); + } + } + + if (!handle.length || $this.dragEl || (!hasTouch && e.button !== 0) || (hasTouch && e.touches.length !== 1)) { + return; + } + + if (e.originalEvent && e.originalEvent.touches) { + e = evt.originalEvent.touches[0]; + } + + $this.delayMove = function(evt) { + + link = false; + + evt.preventDefault(); + $this.dragStart(e); + $this.trigger('start.uk.nestable', [$this]); + + $this.delayMove = false; + }; + + $this.delayMove.x = parseInt(e.pageX, 10); + $this.delayMove.y = parseInt(e.pageY, 10); + $this.delayMove.threshold = $this.options.idlethreshold; + + if (link.length && eEnd == 'touchend') { + + $this.one(eEnd, function(){ + if (link && link.attr('href').trim()) { + location.href = link.attr('href'); + } + }); + } + + e.preventDefault(); + }; + + var onMoveEvent = function(e) { + + if (e.originalEvent && e.originalEvent.touches) { + e = e.originalEvent.touches[0]; + } + + if ($this.delayMove && (Math.abs(e.pageX - $this.delayMove.x) > $this.delayMove.threshold || Math.abs(e.pageY - $this.delayMove.y) > $this.delayMove.threshold)) { + + if (!window.getSelection().toString()) { + $this.delayMove(e); + } else { + $this.delayMove = false; + } + } + + if ($this.dragEl) { + e.preventDefault(); + $this.dragMove(e); + $this.trigger('move.uk.nestable', [$this]); + } + }; + + var onEndEvent = function(e) { + + if ($this.dragEl) { + e.preventDefault(); + $this.dragStop(hasTouch ? e.touches[0] : e); + } + + draggingElement = false; + $this.delayMove = false; + }; + + if (hasTouch) { + this.element[0].addEventListener(eStart, onStartEvent, false); + window.addEventListener(eMove, onMoveEvent, false); + window.addEventListener(eEnd, onEndEvent, false); + window.addEventListener(eCancel, onEndEvent, false); + } else { + this.on(eStart, onStartEvent); + $win.on(eMove, onMoveEvent); + $win.on(eEnd, onEndEvent); + } + + }, + + serialize: function() { + + var data, + depth = 0, + list = this, + step = function(level, depth) { + + var array = [ ], items = level.children(list.options._listItemClass); + + items.each(function() { + + var li = UI.$(this), + item = {}, attribute, + sub = li.children(list.options._listClass); + + for (var i = 0, attr, val; i < li[0].attributes.length; i++) { + attribute = li[0].attributes[i]; + if (attribute.name.indexOf('data-') === 0) { + attr = attribute.name.substr(5); + val = UI.Utils.str2json(attribute.value); + item[attr] = (val || attribute.value=='false' || attribute.value=='0') ? val:attribute.value; + } + } + + if (sub.length) { + item.children = step(sub, depth + 1); + } + + array.push(item); + + }); + return array; + }; + + data = step(list.element, depth); + + return data; + }, + + list: function(options) { + + var data = [], + list = this, + depth = 0, + step = function(level, depth, parent) { + + var items = level.children(options._listItemClass); + + items.each(function(index) { + var li = UI.$(this), + item = UI.$.extend({parent_id: (parent ? parent : null), depth: depth, order: index}, li.data()), + sub = li.children(options._listClass); + + data.push(item); + + if (sub.length) { + step(sub, depth + 1, li.data(options.idProperty || 'id')); + } + }); + }; + + options = UI.$.extend({}, list.options, options); + + step(list.element, depth); + + return data; + }, + + reset: function() { + + this.mouse = { + offsetX : 0, + offsetY : 0, + startX : 0, + startY : 0, + lastX : 0, + lastY : 0, + nowX : 0, + nowY : 0, + distX : 0, + distY : 0, + dirAx : 0, + dirX : 0, + dirY : 0, + lastDirX : 0, + lastDirY : 0, + distAxX : 0, + distAxY : 0 + }; + this.moving = false; + this.dragEl = null; + this.dragRootEl = null; + this.dragDepth = 0; + this.hasNewRoot = false; + this.pointEl = null; + + for (var i=0; i').addClass(this.options.listClass + ' ' + this.options.dragClass).append(dragItem.clone()); + this.dragEl.css('width', dragItem.width()); + this.placeEl.addClass(this.options.placeholderClass); + + draggingElement = this.dragEl; + + this.tmpDragOnSiblings = [dragItem[0].previousSibling, dragItem[0].nextSibling]; + + UI.$body.append(this.dragEl); + + this.dragEl.css({ + left : offset.left, + top : offset.top + }); + + // total depth of dragging item + var i, depth, items = this.dragEl.find(this.options._listItemClass); + + for (i = 0; i < items.length; i++) { + depth = UI.$(items[i]).parents(this.options._listClass+','+this.options._listBaseClass).length; + if (depth > this.dragDepth) { + this.dragDepth = depth; + } + } + + html.addClass(this.options.movingClass); + }, + + dragStop: function(e) { + + var el = UI.$(this.placeEl), + root = this.placeEl.parents(this.options._listBaseClass+':first'); + + this.placeEl.removeClass(this.options.placeholderClass); + this.dragEl.remove(); + + if (this.element[0] !== root[0]) { + + root.trigger('change.uk.nestable',[root.data('nestable'), el, 'added']); + this.element.trigger('change.uk.nestable', [this, el, 'removed']); + + } else { + this.element.trigger('change.uk.nestable',[this, el, "moved"]); + } + + this.trigger('stop.uk.nestable', [this, el]); + + this.reset(); + + html.removeClass(this.options.movingClass); + }, + + dragMove: function(e) { + var list, parent, prev, next, depth, + opt = this.options, + mouse = this.mouse, + maxDepth = this.dragRootEl ? this.dragRootEl.data('nestable').options.maxDepth : opt.maxDepth; + + this.dragEl.css({ + left : e.pageX - mouse.offsetX, + top : e.pageY - mouse.offsetY + }); + + // mouse position last events + mouse.lastX = mouse.nowX; + mouse.lastY = mouse.nowY; + // mouse position this events + mouse.nowX = e.pageX; + mouse.nowY = e.pageY; + // distance mouse moved between events + mouse.distX = mouse.nowX - mouse.lastX; + mouse.distY = mouse.nowY - mouse.lastY; + // direction mouse was moving + mouse.lastDirX = mouse.dirX; + mouse.lastDirY = mouse.dirY; + // direction mouse is now moving (on both axis) + mouse.dirX = mouse.distX === 0 ? 0 : mouse.distX > 0 ? 1 : -1; + mouse.dirY = mouse.distY === 0 ? 0 : mouse.distY > 0 ? 1 : -1; + // axis mouse is now moving on + var newAx = Math.abs(mouse.distX) > Math.abs(mouse.distY) ? 1 : 0; + + // do nothing on first move + if (!mouse.moving) { + mouse.dirAx = newAx; + mouse.moving = true; + return; + } + + // calc distance moved on this axis (and direction) + if (mouse.dirAx !== newAx) { + mouse.distAxX = 0; + mouse.distAxY = 0; + } else { + mouse.distAxX += Math.abs(mouse.distX); + if (mouse.dirX !== 0 && mouse.dirX !== mouse.lastDirX) { + mouse.distAxX = 0; + } + mouse.distAxY += Math.abs(mouse.distY); + if (mouse.dirY !== 0 && mouse.dirY !== mouse.lastDirY) { + mouse.distAxY = 0; + } + } + mouse.dirAx = newAx; + + /** + * move horizontal + */ + if (mouse.dirAx && mouse.distAxX >= opt.threshold) { + // reset move distance on x-axis for new phase + mouse.distAxX = 0; + prev = this.placeEl.prev('li'); + + // increase horizontal level if previous sibling exists, is not collapsed, and does not have a 'no children' class + if (mouse.distX > 0 && prev.length && !prev.hasClass(opt.collapsedClass) && !prev.hasClass(opt.noChildrenClass)) { + + // cannot increase level when item above is collapsed + list = prev.find(opt._listClass).last(); + + // check if depth limit has reached + depth = this.placeEl.parents(opt._listClass+','+opt._listBaseClass).length; + + if (depth + this.dragDepth <= maxDepth) { + + // create new sub-level if one doesn't exist + if (!list.length) { + list = UI.$('