From a122d48d7b6d0854567ecc82087a9d18859d471d Mon Sep 17 00:00:00 2001 From: Marek Skiba Date: Sat, 15 Jul 2017 13:49:15 +0200 Subject: [PATCH] Added autoscroll while dragging, see #71 --- README.md | 15 +++++++++++ jquery.nestable.js | 66 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 471a8b1..c5f65c8 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,18 @@ You can deactivate the plugin by running ```js $('.dd').nestable('destroy'); ``` +### Autoscroll while dragging +Autoscrolls the container element while dragging if you drag the element over the offsets defined in `scrollTriggers` config option. +```js +$('.dd').nestable({ scroll: true }); +``` + +To use this feature you need to have `jQuery >= 1.9` and `scrollParent()` method. +You can be find this method in `jQuery UI` or if you don't want to have `jQuery UI` as a dependency you can use [this repository](https://github.com/slindberg/jquery-scrollparent). + + +You can also control the scroll sensitivity and speed, check `scrollSensitivity` and `scrollSpeed` options. ### On the fly nestable generation @@ -284,6 +295,10 @@ You can change the follow options: * `maxDepth` number of levels an item can be nested (default `5`) * `group` group ID to allow dragging between lists (default `0`) * `callback` callback function when an element has been changed (default `null`) +* `scroll` enable or disable the scrolling behaviour (default: `false`) +* `scrollSensitivity` mouse movement needed to trigger the scroll (default: `1`) +* `scrollSpeed` speed of the scroll (default: `5`) +* `scrollTriggers` distance from the border where scrolling become active (default: `{ top: 40, left: 40, right: -40, bottom: -40 }`) These advanced config options are also available: diff --git a/jquery.nestable.js b/jquery.nestable.js index d5ccd4e..77cb439 100644 --- a/jquery.nestable.js +++ b/jquery.nestable.js @@ -54,6 +54,15 @@ fixedDepth: false, //fixed item's depth fixed: false, includeContent: false, + scroll: false, + scrollSensitivity: 1, + scrollSpeed: 5, + scrollTriggers: { + top: 40, + left: 40, + right: -40, + bottom: -40 + }, callback: function(l, e, p) {}, onDragStart: function(l, e, p) {}, beforeDragStop: function(l, e, p) {}, @@ -248,13 +257,13 @@ { var opts = this.options, el = this.el, - item = this._getItemById(itemId) + item = this._getItemById(itemId); //animation time time = time || 'slow'; //removes item and additional elements from list - function removeItem(item){ + function removeItem(item) { // remove item item = item || this; @@ -272,11 +281,11 @@ if (siblings.length === 0) { $(this).remove(); } - }); + }); } //Setting fade to true, adds fadeOut effect to removing. - if(fade === 'fade'){ + if (fade === 'fade') { item.fadeOut(time, removeItem); } else { @@ -699,7 +708,7 @@ var currentEl = this.el, lastIndex = indexArray.length - 1; - //Put drag elemnt at current element position. + //Put drag element at current element position. function placeElement(currentEl, dragElement) { if(indexArray[lastIndex] === 0) { $(currentEl).prepend(dragElement.clone()); @@ -725,8 +734,8 @@ // fix for zepto.js //this.placeEl.replaceWith(this.dragEl.children(this.options.itemNodeName + ':first').detach()); var position = { - top : e.pageY, - left : e.pageX + top : e.pageY, + left : e.pageX }; //Get indexArray of item at drag start. var srcIndex = this.dragEl.data('indexOfItem'); @@ -805,6 +814,47 @@ return; } + // do scrolling if enable + if (opt.scroll) { + if (typeof jQuery.fn.scrollParent !== 'undefined') { + var scrolled = false; + var scrollParent = this.el.scrollParent()[0]; + if (scrollParent !== document && scrollParent.tagName !== 'HTML') { + if ((opt.scrollTriggers.bottom + scrollParent.offsetHeight) - e.pageY < opt.scrollSensitivity) + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + opt.scrollSpeed; + else if (e.pageY - opt.scrollTriggers.top < opt.scrollSensitivity) + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - opt.scrollSpeed; + + if ((opt.scrollTriggers.right + scrollParent.offsetWidth) - e.pageX < opt.scrollSensitivity) + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + opt.scrollSpeed; + else if (e.pageX - opt.scrollTriggers.left < opt.scrollSensitivity) + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - opt.scrollSpeed; + } else { + if (e.pageY - $(document).scrollTop() < opt.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() - opt.scrollSpeed); + else if($(window).height() - (e.pageY - $(document).scrollTop()) < opt.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() + opt.scrollSpeed); + + if (e.pageX - $(document).scrollLeft() < opt.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() - opt.scrollSpeed); + else if ($(window).width() - (e.pageX - $(document).scrollLeft()) < opt.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() + opt.scrollSpeed); + } + } else { + console.warn('To use scrolling you need to have scrollParent() function, check documentation for more information'); + } + } + + if (this.scrollTimer) { + clearTimeout(this.scrollTimer); + } + + if (opt.scroll && scrolled) { + this.scrollTimer = setTimeout(function() { + $(window).trigger(e); + }, 10); + } + // calc distance moved on this axis (and direction) if(mouse.dirAx !== newAx) { mouse.distAxX = 0; @@ -957,7 +1007,7 @@ if(args.length > 1){ var pluginArgs = []; for (var i = 1; i < args.length; i++) { - pluginArgs.push(args[i]); + pluginArgs.push(args[i]); } retval = plugin[params].apply(plugin, pluginArgs); }