From 68e4f692746299ab49d1ef2ae56dcf63c6d89c44 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 1 Apr 2015 16:24:33 +0900 Subject: [PATCH 01/26] Added two callbacks afterInit onStartEvent --- ...ble.js => jquery.nestable.withCallbacks.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) rename jquery.nestable.js => jquery.nestable.withCallbacks.js (96%) diff --git a/jquery.nestable.js b/jquery.nestable.withCallbacks.js similarity index 96% rename from jquery.nestable.js rename to jquery.nestable.withCallbacks.js index 7323fb4..0d4d1ef 100644 --- a/jquery.nestable.js +++ b/jquery.nestable.withCallbacks.js @@ -1,6 +1,11 @@ /*! * Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/ * Dual-licensed under the BSD or MIT licenses + * + * Modified(1 April 2015): + * Added 2 callbacks + * afterInit + * onStartEvent */ ;(function($, window, document, undefined) { @@ -42,7 +47,10 @@ collapseBtnHTML : '', group : 0, maxDepth : 5, - threshold : 20 + threshold : 20, + /* callback */ + afterInit: null, + onStartEvent: null, }; function Plugin(element, options) @@ -103,6 +111,11 @@ return; } + /* callback for onStartEvent */ + if (typeof this.options.onStartEvent == 'function') { + this.options.onStartEvent.call(e); + } + e.preventDefault(); list.dragStart(e.touches ? e.touches[0] : e); }; @@ -134,6 +147,10 @@ list.w.on('mousemove', onMoveEvent); list.w.on('mouseup', onEndEvent); + /* callback for init () */ + if (typeof this.options.afterInit == 'function') { + list.options.afterInit.call(list); + } }, serialize: function() From e2027b0e3775382541e6a8d487a1959560d82ea9 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 1 Apr 2015 21:59:41 +0900 Subject: [PATCH 02/26] added 2 more callbacks --- jquery.nestable.withCallbacks.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 0d4d1ef..3219c9c 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -3,9 +3,8 @@ * Dual-licensed under the BSD or MIT licenses * * Modified(1 April 2015): - * Added 2 callbacks - * afterInit - * onStartEvent + * Added 4 callbacks + * afterInit, onStartEvent, onMoveEvent, onEndEvent */ ;(function($, window, document, undefined) { @@ -51,6 +50,8 @@ /* callback */ afterInit: null, onStartEvent: null, + onMoveEvent: null, + onEndEvent: null, }; function Plugin(element, options) @@ -125,6 +126,10 @@ if (list.dragEl) { e.preventDefault(); list.dragMove(e.touches ? e.touches[0] : e); + /* callback for onMoveEvent */ + if (typeof this.options.onMoveEvent == 'function') { + this.options.onMoveEvent.call(e); + } } }; @@ -133,6 +138,10 @@ if (list.dragEl) { e.preventDefault(); list.dragStop(e.touches ? e.touches[0] : e); + /* callback for onEndEvent */ + if (typeof this.options.onEndEvent == 'function') { + this.options.onEndEvent.call(e); + } } }; From ac395cdf07d3355349fc422945d035de0f6921c4 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 1 Apr 2015 22:01:12 +0900 Subject: [PATCH 03/26] Update README.md --- README.md | 103 +++--------------------------------------------------- 1 file changed, 4 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index b86e091..22bf693 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,12 @@ -Nestable +Nestable with 4 little callbacks ======== -## PLEASE NOTE +## This is a modified version of Nestable -**I cannot provide any support or guidance beyond this README. If this code helps you that's great but I have no plans to develop Nestable beyond this demo (it's not a final product and has limited functionality). I cannot reply to any requests for help.** +Original can be found here: https://github.com/dbushell/Nestable * * * -### Drag & drop hierarchical list with mouse and touch compatibility (jQuery / Zepto plugin) - -[**Try Nestable Demo**](http://dbushell.github.com/Nestable/) - -Nestable is an experimental example and not under active development. If it suits your requirements feel free to expand upon it! - -## Usage - -Write your nested HTML lists like so: - -
-
    -
  1. -
    Item 1
    -
  2. -
  3. -
    Item 2
    -
  4. -
  5. -
    Item 3
    -
      -
    1. -
      Item 4
      -
    2. -
    3. -
      Item 5
      -
    4. -
    -
  6. -
-
- -Then activate with jQuery like so: - - $('.dd').nestable({ /* config options */ }); - -### Events - -The `change` event is fired when items are reordered. - - $('.dd').on('change', function() { - /* on change event */ - }); - -### Methods - -You can get a serialised object with all `data-*` attributes for each item. - - $('.dd').nestable('serialize'); - -The serialised JSON for the example above would be: - - [{"id":1},{"id":2},{"id":3,"children":[{"id":4},{"id":5}]}] - -### Configuration - -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`) - -These advanced config options are also available: - -* `listNodeName` The HTML element to create for lists (default `'ol'`) -* `itemNodeName` The HTML element to create for list items (default `'li'`) -* `rootClass` The class of the root element `.nestable()` was used on (default `'dd'`) -* `listClass` The class of all list elements (default `'dd-list'`) -* `itemClass` The class of all list item elements (default `'dd-item'`) -* `dragClass` The class applied to the list element that is being dragged (default `'dd-dragel'`) -* `handleClass` The class of the content element inside each list item (default `'dd-handle'`) -* `collapsedClass` The class applied to lists that have been collapsed (default `'dd-collapsed'`) -* `placeClass` The class of the placeholder element (default `'dd-placeholder'`) -* `emptyClass` The class used for empty list placeholder elements (default `'dd-empty'`) -* `expandBtnHTML` The HTML text used to generate a list item expand button (default `''`) -* `collapseBtnHTML` The HTML text used to generate a list item collapse button (default `''`) - -**Inspect the [Nestable Demo](http://dbushell.github.com/Nestable/) for guidance.** - -## Change Log - -### 15th October 2012 - -* Merge for Zepto.js support -* Merge fix for remove/detach items - -### 27th June 2012 - -* Added `maxDepth` option (default to 5) -* Added empty placeholder -* Updated CSS class structure with options for `listClass` and `itemClass`. -* Fixed to allow drag and drop between multiple Nestable instances (off by default). -* Added `group` option to enabled the above. - -* * * - -Author: David Bushell [http://dbushell.com](http://dbushell.com/) [@dbushell](http://twitter.com/dbushell/) +Original Author: David Bushell [http://dbushell.com](http://dbushell.com/) [@dbushell](http://twitter.com/dbushell/) Copyright © 2012 David Bushell | BSD & MIT license From 3417a3f0e317c518398da16b1e7496d7ab877e18 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 1 Apr 2015 22:49:29 +0900 Subject: [PATCH 04/26] Bug fix --- jquery.nestable.withCallbacks.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 3219c9c..e62a246 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -3,8 +3,9 @@ * Dual-licensed under the BSD or MIT licenses * * Modified(1 April 2015): - * Added 4 callbacks - * afterInit, onStartEvent, onMoveEvent, onEndEvent + * Added 2 callbacks + * afterInit + * onStartEvent */ ;(function($, window, document, undefined) { @@ -113,8 +114,8 @@ } /* callback for onStartEvent */ - if (typeof this.options.onStartEvent == 'function') { - this.options.onStartEvent.call(e); + if (typeof list.options.onStartEvent == 'function') { + list.options.onStartEvent.call(list, e); } e.preventDefault(); @@ -127,8 +128,8 @@ e.preventDefault(); list.dragMove(e.touches ? e.touches[0] : e); /* callback for onMoveEvent */ - if (typeof this.options.onMoveEvent == 'function') { - this.options.onMoveEvent.call(e); + if (typeof list.options.onMoveEvent == 'function') { + list.options.onMoveEvent.call(list, e); } } }; @@ -139,8 +140,8 @@ e.preventDefault(); list.dragStop(e.touches ? e.touches[0] : e); /* callback for onEndEvent */ - if (typeof this.options.onEndEvent == 'function') { - this.options.onEndEvent.call(e); + if (typeof list.options.onEndEvent == 'function') { + list.options.onEndEvent.call(list, e); } } }; @@ -157,7 +158,7 @@ list.w.on('mouseup', onEndEvent); /* callback for init () */ - if (typeof this.options.afterInit == 'function') { + if (typeof list.options.afterInit == 'function') { list.options.afterInit.call(list); } }, From 9841b3f096a73f3d338a60b72271b50528a1a968 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 1 Apr 2015 22:54:06 +0900 Subject: [PATCH 05/26] Update README.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 22bf693..204cd69 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,23 @@ Nestable with 4 little callbacks Original can be found here: https://github.com/dbushell/Nestable +## Example +``` +$('#example-list-element').nestable({ + afterInit: function () { + console.log('afterInit'); + }, + onStartEvent: function ( _event ) { + console.log('onStartEvent',_event); + }, + onMoveEvent: function ( _event ) { + console.log('onMoveEvent',_event); + }, + onEndEvent: function ( _event ) { + console.log('onEndEvent',_event); + }, +}); +``` * * * Original Author: David Bushell [http://dbushell.com](http://dbushell.com/) [@dbushell](http://twitter.com/dbushell/) From 389cf0e898db250e60cabcd446b7e2ecaec73ba7 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 4 Apr 2015 22:00:38 +0900 Subject: [PATCH 06/26] Using trigger upon bigfoot90's suggestion --- jquery.nestable.withCallbacks.js | 45 +++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index e62a246..0f1f214 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -50,9 +50,6 @@ threshold : 20, /* callback */ afterInit: null, - onStartEvent: null, - onMoveEvent: null, - onEndEvent: null, }; function Plugin(element, options) @@ -113,13 +110,16 @@ return; } - /* callback for onStartEvent */ - if (typeof list.options.onStartEvent == 'function') { - list.options.onStartEvent.call(list, e); - } - e.preventDefault(); list.dragStart(e.touches ? e.touches[0] : e); + + /* callback for dragStart */ + var item = list.dragEl.find('.'+list.options.itemClass); + list.dragRootEl.trigger('dragStart', [ + item, // List item + list.el, // Source list + list.dragRootEl // Destination list + ]); }; var onMoveEvent = function(e) @@ -127,10 +127,13 @@ if (list.dragEl) { e.preventDefault(); list.dragMove(e.touches ? e.touches[0] : e); - /* callback for onMoveEvent */ - if (typeof list.options.onMoveEvent == 'function') { - list.options.onMoveEvent.call(list, e); - } + /* callback for dragMove */ + var item = list.dragEl.find('.'+list.options.itemClass); + list.dragRootEl.trigger('dragMove', [ + item, // List item + list.el, // Source list + list.dragRootEl // Destination list + ]); } }; @@ -138,11 +141,16 @@ { if (list.dragEl) { e.preventDefault(); + + /* callback for dragEnd */ + var item = list.dragEl.find('.'+list.options.itemClass); + list.dragRootEl.trigger('dragEnd', [ + item, // List item + list.el, // Source list + list.dragRootEl // Destination list + ]); + list.dragStop(e.touches ? e.touches[0] : e); - /* callback for onEndEvent */ - if (typeof list.options.onEndEvent == 'function') { - list.options.onEndEvent.call(list, e); - } } }; @@ -157,9 +165,10 @@ list.w.on('mousemove', onMoveEvent); list.w.on('mouseup', onEndEvent); - /* callback for init () */ + /* callback for init () */ if (typeof list.options.afterInit == 'function') { - list.options.afterInit.call(list); + console.log(list); + list.options.afterInit.call(window, this); } }, From ce0c0ec5f1abe429d786f10c3b626bf8996dfaee Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 4 Apr 2015 22:03:21 +0900 Subject: [PATCH 07/26] example changed --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 204cd69..a1b20b8 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,20 @@ Original can be found here: https://github.com/dbushell/Nestable ## Example ``` $('#example-list-element').nestable({ - afterInit: function () { - console.log('afterInit'); - }, - onStartEvent: function ( _event ) { - console.log('onStartEvent',_event); - }, - onMoveEvent: function ( _event ) { - console.log('onMoveEvent',_event); - }, - onEndEvent: function ( _event ) { - console.log('onEndEvent',_event); - }, -}); + 'maxDepth': 3, + afterInit: function ( event ) { + console.log( event ); + } +}) + .on('dragStart', function(event, item, source, destination) { + console.log('dragStart', item, source, destination); + }) + .on('dragEnd', function(event, item, source, destination) { + console.log('dragEnd', item, source, destination); + }) + .on('dragMove', function(event, item, source, destination) { + console.log('dragMove', item, source, destination); + }); ``` * * * From 29a6b27b11bd75d51490c368470ffa96dc994625 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 4 Apr 2015 22:34:15 +0900 Subject: [PATCH 08/26] Forgot removing a debug line --- jquery.nestable.withCallbacks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 0f1f214..be30b4d 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -165,9 +165,8 @@ list.w.on('mousemove', onMoveEvent); list.w.on('mouseup', onEndEvent); - /* callback for init () */ + /* callback for afterInit */ if (typeof list.options.afterInit == 'function') { - console.log(list); list.options.afterInit.call(window, this); } }, From 89c9ee03150b96bbb2699a44d840a7e81e96fb40 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 4 Apr 2015 22:41:56 +0900 Subject: [PATCH 09/26] forgot including "list" which trigger returns --- jquery.nestable.withCallbacks.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index be30b4d..777762e 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -116,6 +116,7 @@ /* callback for dragStart */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragStart', [ + list, item, // List item list.el, // Source list list.dragRootEl // Destination list @@ -130,6 +131,7 @@ /* callback for dragMove */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragMove', [ + list, item, // List item list.el, // Source list list.dragRootEl // Destination list @@ -145,6 +147,7 @@ /* callback for dragEnd */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragEnd', [ + list, item, // List item list.el, // Source list list.dragRootEl // Destination list From 597e0f3061b197c91161d163b729dd5ccfdcadb5 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 00:02:37 +0900 Subject: [PATCH 10/26] added dragJustBeforeStart callback --- jquery.nestable.withCallbacks.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 777762e..9b50d0c 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -94,6 +94,7 @@ var onStartEvent = function(e) { var handle = $(e.target); + if (!handle.hasClass(list.options.handleClass)) { if (handle.closest('.' + list.options.noDragClass).length) { return; @@ -110,16 +111,19 @@ return; } + /* callback for dragJustBeforeStart */ + list.el.trigger('dragJustBeforeStart', [list]); + e.preventDefault(); list.dragStart(e.touches ? e.touches[0] : e); - /* callback for dragStart */ + /* callback for dragStart */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragStart', [ list, item, // List item list.el, // Source list - list.dragRootEl // Destination list + list.dragRootEl, // Destination list ]); }; From e8ae79982f6968a1c9fb6bce198ebc62c42bab72 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 00:04:01 +0900 Subject: [PATCH 11/26] updated with dragJustBeforeStart example --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1b20b8..41c3f80 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,17 @@ $('#example-list-element').nestable({ console.log( event ); } }) + .on('dragJustBeforeStart', function(event) { + console.log('dragStart', event); + }) .on('dragStart', function(event, item, source, destination) { - console.log('dragStart', item, source, destination); + console.log('dragStart', event, item, source, destination); }) .on('dragEnd', function(event, item, source, destination) { - console.log('dragEnd', item, source, destination); + console.log('dragEnd', event, item, source, destination); }) .on('dragMove', function(event, item, source, destination) { - console.log('dragMove', item, source, destination); + console.log('dragMove', event, item, source, destination); }); ``` * * * From a3e8b208b5a52d3bc1d651654fc762c6ec16e7c8 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 00:04:31 +0900 Subject: [PATCH 12/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41c3f80..2b9fd40 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Nestable with 4 little callbacks +Nestable with 5 little callbacks ======== ## This is a modified version of Nestable From ecf0343be8692726d2f1f827b324e77c2b1feb2f Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 00:23:44 +0900 Subject: [PATCH 13/26] dragJustBeforeStart returns handle removed unnecessary variables to be returned (they were redundant) --- jquery.nestable.withCallbacks.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 9b50d0c..06868b4 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -95,6 +95,9 @@ { var handle = $(e.target); + /* callback for dragJustBeforeStart */ + list.el.trigger('dragJustBeforeStart', [handle]); + if (!handle.hasClass(list.options.handleClass)) { if (handle.closest('.' + list.options.noDragClass).length) { return; @@ -111,16 +114,12 @@ return; } - /* callback for dragJustBeforeStart */ - list.el.trigger('dragJustBeforeStart', [list]); - e.preventDefault(); list.dragStart(e.touches ? e.touches[0] : e); /* callback for dragStart */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragStart', [ - list, item, // List item list.el, // Source list list.dragRootEl, // Destination list @@ -135,7 +134,6 @@ /* callback for dragMove */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragMove', [ - list, item, // List item list.el, // Source list list.dragRootEl // Destination list @@ -151,7 +149,6 @@ /* callback for dragEnd */ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragEnd', [ - list, item, // List item list.el, // Source list list.dragRootEl // Destination list From dcd85a7e2e1339314b538ac139449fecc51016ac Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 00:24:18 +0900 Subject: [PATCH 14/26] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b9fd40..560dbb1 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ $('#example-list-element').nestable({ console.log( event ); } }) - .on('dragJustBeforeStart', function(event) { - console.log('dragStart', event); + .on('dragJustBeforeStart', function(handle) { + console.log('dragStart', handle); }) .on('dragStart', function(event, item, source, destination) { console.log('dragStart', event, item, source, destination); From b2bb95c76d50b3cd86c03206b912de53f26f7e24 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 01:20:51 +0900 Subject: [PATCH 15/26] Destination list of dragStart callback removed --- jquery.nestable.withCallbacks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 06868b4..18b79d4 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -121,8 +121,7 @@ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragStart', [ item, // List item - list.el, // Source list - list.dragRootEl, // Destination list + list.el // Source list ]); }; From fe05fe8e2176158ac7ce5e4a7f39dc8870e65380 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 01:21:34 +0900 Subject: [PATCH 16/26] Destination list removed where unnecessary --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 560dbb1..0cfa57a 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ $('#example-list-element').nestable({ .on('dragJustBeforeStart', function(handle) { console.log('dragStart', handle); }) - .on('dragStart', function(event, item, source, destination) { - console.log('dragStart', event, item, source, destination); + .on('dragStart', function(event, item, source) { + console.log('dragStart', event, item, source); }) .on('dragEnd', function(event, item, source, destination) { console.log('dragEnd', event, item, source, destination); }) .on('dragMove', function(event, item, source, destination) { - console.log('dragMove', event, item, source, destination); + console.log('dragMove', event, item, source); }); ``` * * * From 23e07168964f5acd3e7c75fdcdb5602aa83bfa4d Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 01:22:15 +0900 Subject: [PATCH 17/26] Destination list removed from onMoveEvent --- jquery.nestable.withCallbacks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 18b79d4..8f2fcad 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -134,8 +134,7 @@ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragMove', [ item, // List item - list.el, // Source list - list.dragRootEl // Destination list + list.el // Source list ]); } }; From 6dd9d4b1f24c9ad183fc5047cbc1e79240d1bbf4 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 01:23:27 +0900 Subject: [PATCH 18/26] unnecessary settings in the example removed --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 0cfa57a..f6345f0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Original can be found here: https://github.com/dbushell/Nestable ## Example ``` $('#example-list-element').nestable({ - 'maxDepth': 3, afterInit: function ( event ) { console.log( event ); } From 0f3282d70067a8e67dbcb02d50c56498ce592b25 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 5 Apr 2015 15:17:05 +0900 Subject: [PATCH 19/26] Destination for dragMove readded --- jquery.nestable.withCallbacks.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 8f2fcad..0b921de 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -134,7 +134,8 @@ var item = list.dragEl.find('.'+list.options.itemClass); list.dragRootEl.trigger('dragMove', [ item, // List item - list.el // Source list + list.el, // Source list + list.dragRootEl // Destination ]); } }; From d2fd7d41182fd964d4be21759c6de1587d98cb68 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Mon, 4 May 2015 20:58:27 +0900 Subject: [PATCH 20/26] Update README.md --- README.md | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index f6345f0..eb3810f 100644 --- a/README.md +++ b/README.md @@ -12,21 +12,34 @@ $('#example-list-element').nestable({ console.log( event ); } }) - .on('dragJustBeforeStart', function(handle) { - console.log('dragStart', handle); - }) - .on('dragStart', function(event, item, source) { - console.log('dragStart', event, item, source); - }) - .on('dragEnd', function(event, item, source, destination) { - console.log('dragEnd', event, item, source, destination); - }) - .on('dragMove', function(event, item, source, destination) { - console.log('dragMove', event, item, source); - }); +.on('dragJustBeforeStart', function(handle) { + console.log('dragStart', handle); +}) +.on('dragStart', function(event, item, source) { + console.log('dragStart', event, item, source); +}) +.on('dragEnd', function(event, item, source, destination) { + console.log('dragEnd', event, item, source, destination); +}) +.on('beforeDragEnd', function(event, item, source, destination, position, feedback) { + if (source[0] === destination[0]) return; + feedback.abort = !window.confirm('Continue?'); +}) +.on('dragEnd', function(event, item, source, destination, position) { + if (source[0] === destination[0]) return; + + // Make an ajax request to persist move on database + // here i need to pass item-id, source-id, destination-id, position index to the server + // .... +}) +.on('dragMove', function(event, item, source, destination) { + console.log('dragMove', event, item, source); +}); ``` * * * Original Author: David Bushell [http://dbushell.com](http://dbushell.com/) [@dbushell](http://twitter.com/dbushell/) +Big thanks to @bigfoot90 ! + Copyright © 2012 David Bushell | BSD & MIT license From 30f395b8efb7306592cd62b764fc169ce12e676b Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Mon, 4 May 2015 21:00:31 +0900 Subject: [PATCH 21/26] added beforeDragEnd Thanks to bigfoot90 --- jquery.nestable.withCallbacks.js | 1039 +++++++++++++++--------------- 1 file changed, 529 insertions(+), 510 deletions(-) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.withCallbacks.js index 0b921de..3226fad 100644 --- a/jquery.nestable.withCallbacks.js +++ b/jquery.nestable.withCallbacks.js @@ -2,521 +2,540 @@ * Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/ * Dual-licensed under the BSD or MIT licenses * - * Modified(1 April 2015): - * Added 2 callbacks + * Modified : + * Added a few callbacks * afterInit - * onStartEvent + * dragJustBeforeStart + * dragStart + * beforeDragEnd + * dragEnd + * dragMove */ ;(function($, window, document, undefined) { - var hasTouch = 'ontouchstart' in document; - - /** - * Detect CSS pointer-events property - * events are normally disabled on the dragging element to avoid conflicts - * https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js - */ - var hasPointerEvents = (function() - { - var el = document.createElement('div'), - docEl = document.documentElement; - if (!('pointerEvents' in el.style)) { - return false; - } - el.style.pointerEvents = 'auto'; - el.style.pointerEvents = 'x'; - docEl.appendChild(el); - var supports = window.getComputedStyle && window.getComputedStyle(el, '').pointerEvents === 'auto'; - docEl.removeChild(el); - return !!supports; - })(); - - var defaults = { - listNodeName : 'ol', - itemNodeName : 'li', - rootClass : 'dd', - listClass : 'dd-list', - itemClass : 'dd-item', - dragClass : 'dd-dragel', - handleClass : 'dd-handle', - collapsedClass : 'dd-collapsed', - placeClass : 'dd-placeholder', - noDragClass : 'dd-nodrag', - emptyClass : 'dd-empty', - expandBtnHTML : '', - collapseBtnHTML : '', - group : 0, - maxDepth : 5, - threshold : 20, - /* callback */ - afterInit: null, - }; - - function Plugin(element, options) - { - this.w = $(document); - this.el = $(element); - this.options = $.extend({}, defaults, options); - this.init(); - } - - Plugin.prototype = { - - init: function() - { - var list = this; - - list.reset(); - - list.el.data('nestable-group', this.options.group); - - list.placeEl = $('
'); - - $.each(this.el.find(list.options.itemNodeName), function(k, el) { - list.setParent($(el)); - }); - - list.el.on('click', 'button', function(e) { - if (list.dragEl) { - return; - } - var target = $(e.currentTarget), - action = target.data('action'), - item = target.parent(list.options.itemNodeName); - if (action === 'collapse') { - list.collapseItem(item); - } - if (action === 'expand') { - list.expandItem(item); - } - }); - - var onStartEvent = function(e) - { - var handle = $(e.target); - - /* callback for dragJustBeforeStart */ - list.el.trigger('dragJustBeforeStart', [handle]); - - if (!handle.hasClass(list.options.handleClass)) { - if (handle.closest('.' + list.options.noDragClass).length) { - return; - } - handle = handle.closest('.' + list.options.handleClass); - } - - if (!handle.length || list.dragEl) { - return; - } - - list.isTouch = /^touch/.test(e.type); - if (list.isTouch && e.touches.length !== 1) { - return; - } - - e.preventDefault(); - list.dragStart(e.touches ? e.touches[0] : e); - - /* callback for dragStart */ - var item = list.dragEl.find('.'+list.options.itemClass); - list.dragRootEl.trigger('dragStart', [ - item, // List item - list.el // Source list - ]); - }; - - var onMoveEvent = function(e) - { - if (list.dragEl) { - e.preventDefault(); - list.dragMove(e.touches ? e.touches[0] : e); - /* callback for dragMove */ - var item = list.dragEl.find('.'+list.options.itemClass); - list.dragRootEl.trigger('dragMove', [ - item, // List item - list.el, // Source list - list.dragRootEl // Destination - ]); - } - }; - - var onEndEvent = function(e) - { - if (list.dragEl) { - e.preventDefault(); - - /* callback for dragEnd */ - var item = list.dragEl.find('.'+list.options.itemClass); - list.dragRootEl.trigger('dragEnd', [ - item, // List item - list.el, // Source list - list.dragRootEl // Destination list - ]); - - list.dragStop(e.touches ? e.touches[0] : e); - } - }; - - if (hasTouch) { - list.el[0].addEventListener('touchstart', onStartEvent, false); - window.addEventListener('touchmove', onMoveEvent, false); - window.addEventListener('touchend', onEndEvent, false); - window.addEventListener('touchcancel', onEndEvent, false); - } - - list.el.on('mousedown', onStartEvent); - list.w.on('mousemove', onMoveEvent); - list.w.on('mouseup', onEndEvent); + var hasTouch = 'ontouchstart' in document; + + /** + * Detect CSS pointer-events property + * events are normally disabled on the dragging element to avoid conflicts + * https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js + */ + var hasPointerEvents = (function() + { + var el = document.createElement('div'), + docEl = document.documentElement; + if (!('pointerEvents' in el.style)) { + return false; + } + el.style.pointerEvents = 'auto'; + el.style.pointerEvents = 'x'; + docEl.appendChild(el); + var supports = window.getComputedStyle && window.getComputedStyle(el, '').pointerEvents === 'auto'; + docEl.removeChild(el); + return !!supports; + })(); + + var defaults = { + listNodeName : 'ol', + itemNodeName : 'li', + rootClass : 'dd', + listClass : 'dd-list', + itemClass : 'dd-item', + dragClass : 'dd-dragel', + handleClass : 'dd-handle', + collapsedClass : 'dd-collapsed', + placeClass : 'dd-placeholder', + noDragClass : 'dd-nodrag', + emptyClass : 'dd-empty', + expandBtnHTML : '', + collapseBtnHTML : '', + group : 0, + maxDepth : 5, + threshold : 20, + /* callback */ + afterInit: null, + }; + + function Plugin(element, options) + { + this.w = $(document); + this.el = $(element); + this.options = $.extend({}, defaults, options); + this.init(); + } + + Plugin.prototype = { + + init: function() + { + var list = this; + + list.reset(); + + list.el.data('nestable-group', this.options.group); + + list.placeEl = $('
'); + + $.each(this.el.find(list.options.itemNodeName), function(k, el) { + list.setParent($(el)); + }); + + list.el.on('click', 'button', function(e) { + if (list.dragEl) { + return; + } + var target = $(e.currentTarget), + action = target.data('action'), + item = target.parent(list.options.itemNodeName); + if (action === 'collapse') { + list.collapseItem(item); + } + if (action === 'expand') { + list.expandItem(item); + } + }); + + var onStartEvent = function(e) + { + var handle = $(e.target); + + /* callback for dragJustBeforeStart */ + list.el.trigger('dragJustBeforeStart', [handle]); + + if (!handle.hasClass(list.options.handleClass)) { + if (handle.closest('.' + list.options.noDragClass).length) { + return; + } + handle = handle.closest('.' + list.options.handleClass); + } + + if (!handle.length || list.dragEl) { + return; + } + + list.isTouch = /^touch/.test(e.type); + if (list.isTouch && e.touches.length !== 1) { + return; + } + + e.preventDefault(); + list.dragStart(e.touches ? e.touches[0] : e); + + /* callback for dragStart */ + var item = list.dragEl.find('.'+list.options.itemClass); + list.dragRootEl.trigger('dragStart', [ + item, // List item + list.el // Source list + ]); + }; + + var onMoveEvent = function(e) + { + if (list.dragEl) { + e.preventDefault(); + list.dragMove(e.touches ? e.touches[0] : e); + /* callback for dragMove */ + var item = list.dragEl.find('.'+list.options.itemClass); + list.dragRootEl.trigger('dragMove', [ + item, // List item + list.el, // Source list + list.dragRootEl // Destination + ]); + } + }; + + var onEndEvent = function(e) + { + if (!list.dragEl) return; + e.preventDefault(); + + var feedback = {abort: false}; + + var item = list.dragEl.find('.'+list.options.itemClass); + var sourceList = list.el; + var destinationList = list.dragRootEl; + var position = list.placeEl.index(); + + destinationList.trigger('beforeDragEnd', [ + item, // List item + sourceList, // Source list + destinationList, // Destination list + position, // Position + feedback + ]); + + if (feedback.abort) return; + + list.dragStop(e.touches ? e.touches[0] : e); + + destinationList.trigger('dragEnd', [ + item, // List item + sourceList, // Source list + destinationList, // Destination list + position // Position + ]); + }; + + if (hasTouch) { + list.el[0].addEventListener('touchstart', onStartEvent, false); + window.addEventListener('touchmove', onMoveEvent, false); + window.addEventListener('touchend', onEndEvent, false); + window.addEventListener('touchcancel', onEndEvent, false); + } + + list.el.on('mousedown', onStartEvent); + list.w.on('mousemove', onMoveEvent); + list.w.on('mouseup', onEndEvent); /* callback for afterInit */ - if (typeof list.options.afterInit == 'function') { - list.options.afterInit.call(window, this); - } - }, - - serialize: function() - { - var data, - depth = 0, - list = this; - step = function(level, depth) - { - var array = [ ], - items = level.children(list.options.itemNodeName); - items.each(function() - { - var li = $(this), - item = $.extend({}, li.data()), - sub = li.children(list.options.listNodeName); - if (sub.length) { - item.children = step(sub, depth + 1); - } - array.push(item); - }); - return array; - }; - data = step(list.el.find(list.options.listNodeName).first(), depth); - return data; - }, - - serialise: function() - { - return this.serialize(); - }, - - 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.isTouch = false; - this.moving = false; - this.dragEl = null; - this.dragRootEl = null; - this.dragDepth = 0; - this.hasNewRoot = false; - this.pointEl = null; - }, - - expandItem: function(li) - { - li.removeClass(this.options.collapsedClass); - li.children('[data-action="expand"]').hide(); - li.children('[data-action="collapse"]').show(); - li.children(this.options.listNodeName).show(); - }, - - collapseItem: function(li) - { - var lists = li.children(this.options.listNodeName); - if (lists.length) { - li.addClass(this.options.collapsedClass); - li.children('[data-action="collapse"]').hide(); - li.children('[data-action="expand"]').show(); - li.children(this.options.listNodeName).hide(); - } - }, - - expandAll: function() - { - var list = this; - list.el.find(list.options.itemNodeName).each(function() { - list.expandItem($(this)); - }); - }, - - collapseAll: function() - { - var list = this; - list.el.find(list.options.itemNodeName).each(function() { - list.collapseItem($(this)); - }); - }, - - setParent: function(li) - { - if (li.children(this.options.listNodeName).length) { - li.prepend($(this.options.expandBtnHTML)); - li.prepend($(this.options.collapseBtnHTML)); - } - li.children('[data-action="expand"]').hide(); - }, - - unsetParent: function(li) - { - li.removeClass(this.options.collapsedClass); - li.children('[data-action]').remove(); - li.children(this.options.listNodeName).remove(); - }, - - dragStart: function(e) - { - var mouse = this.mouse, - target = $(e.target), - dragItem = target.closest(this.options.itemNodeName); - - this.placeEl.css('height', dragItem.height()); - - mouse.offsetX = e.offsetX !== undefined ? e.offsetX : e.pageX - target.offset().left; - mouse.offsetY = e.offsetY !== undefined ? e.offsetY : e.pageY - target.offset().top; - mouse.startX = mouse.lastX = e.pageX; - mouse.startY = mouse.lastY = e.pageY; - - this.dragRootEl = this.el; - - this.dragEl = $(document.createElement(this.options.listNodeName)).addClass(this.options.listClass + ' ' + this.options.dragClass); - this.dragEl.css('width', dragItem.width()); - - dragItem.after(this.placeEl); - dragItem[0].parentNode.removeChild(dragItem[0]); - dragItem.appendTo(this.dragEl); - - $(document.body).append(this.dragEl); - this.dragEl.css({ - 'left' : e.pageX - mouse.offsetX, - 'top' : e.pageY - mouse.offsetY - }); - // total depth of dragging item - var i, depth, - items = this.dragEl.find(this.options.itemNodeName); - for (i = 0; i < items.length; i++) { - depth = $(items[i]).parents(this.options.listNodeName).length; - if (depth > this.dragDepth) { - this.dragDepth = depth; - } - } - }, - - dragStop: function(e) - { - var el = this.dragEl.children(this.options.itemNodeName).first(); - el[0].parentNode.removeChild(el[0]); - this.placeEl.replaceWith(el); - - this.dragEl.remove(); - this.el.trigger('change'); - if (this.hasNewRoot) { - this.dragRootEl.trigger('change'); - } - this.reset(); - }, - - dragMove: function(e) - { - var list, parent, prev, next, depth, - opt = this.options, - mouse = this.mouse; - - 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(opt.itemNodeName); - // increase horizontal level if previous sibling exists and is not collapsed - if (mouse.distX > 0 && prev.length && !prev.hasClass(opt.collapsedClass)) { - // cannot increase level when item above is collapsed - list = prev.find(opt.listNodeName).last(); - // check if depth limit has reached - depth = this.placeEl.parents(opt.listNodeName).length; - if (depth + this.dragDepth <= opt.maxDepth) { - // create new sub-level if one doesn't exist - if (!list.length) { - list = $('<' + opt.listNodeName + '/>').addClass(opt.listClass); - list.append(this.placeEl); - prev.append(list); - this.setParent(prev); - } else { - // else append to next level up - list = prev.children(opt.listNodeName).last(); - list.append(this.placeEl); - } - } - } - // decrease horizontal level - if (mouse.distX < 0) { - // we can't decrease a level if an item preceeds the current one - next = this.placeEl.next(opt.itemNodeName); - if (!next.length) { - parent = this.placeEl.parent(); - this.placeEl.closest(opt.itemNodeName).after(this.placeEl); - if (!parent.children().length) { - this.unsetParent(parent.parent()); - } - } - } - } - - var isEmpty = false; - - // find list item under cursor - if (!hasPointerEvents) { - this.dragEl[0].style.visibility = 'hidden'; - } - this.pointEl = $(document.elementFromPoint(e.pageX - document.body.scrollLeft, e.pageY - (window.pageYOffset || document.documentElement.scrollTop))); - if (!hasPointerEvents) { - this.dragEl[0].style.visibility = 'visible'; - } - if (this.pointEl.hasClass(opt.handleClass)) { - this.pointEl = this.pointEl.parent(opt.itemNodeName); - } - if (this.pointEl.hasClass(opt.emptyClass)) { - isEmpty = true; - } - else if (!this.pointEl.length || !this.pointEl.hasClass(opt.itemClass)) { - return; - } - - // find parent list of item under cursor - var pointElRoot = this.pointEl.closest('.' + opt.rootClass), - isNewRoot = this.dragRootEl.data('nestable-id') !== pointElRoot.data('nestable-id'); - - /** - * move vertical - */ - if (!mouse.dirAx || isNewRoot || isEmpty) { - // check if groups match if dragging over new root - if (isNewRoot && opt.group !== pointElRoot.data('nestable-group')) { - return; - } - // check depth limit - depth = this.dragDepth - 1 + this.pointEl.parents(opt.listNodeName).length; - if (depth > opt.maxDepth) { - return; - } - var before = e.pageY < (this.pointEl.offset().top + this.pointEl.height() / 2); - parent = this.placeEl.parent(); - // if empty create new list to replace empty placeholder - if (isEmpty) { - list = $(document.createElement(opt.listNodeName)).addClass(opt.listClass); - list.append(this.placeEl); - this.pointEl.replaceWith(list); - } - else if (before) { - this.pointEl.before(this.placeEl); - } - else { - this.pointEl.after(this.placeEl); - } - if (!parent.children().length) { - this.unsetParent(parent.parent()); - } - if (!this.dragRootEl.find(opt.itemNodeName).length) { - this.dragRootEl.append('
'); - } - // parent root list has changed - if (isNewRoot) { - this.dragRootEl = pointElRoot; - this.hasNewRoot = this.el[0] !== this.dragRootEl[0]; - } - } - } - - }; - - $.fn.nestable = function(params) - { - var lists = this, - retval = this; - - lists.each(function() - { - var plugin = $(this).data("nestable"); - - if (!plugin) { - $(this).data("nestable", new Plugin(this, params)); - $(this).data("nestable-id", new Date().getTime()); - } else { - if (typeof params === 'string' && typeof plugin[params] === 'function') { - retval = plugin[params](); - } - } - }); - - return retval || lists; - }; + if (typeof list.options.afterInit == 'function') { + list.options.afterInit.call(window, this); + } + }, + + serialize: function() + { + var data, + depth = 0, + list = this; + step = function(level, depth) + { + var array = [ ], + items = level.children(list.options.itemNodeName); + items.each(function() + { + var li = $(this), + item = $.extend({}, li.data()), + sub = li.children(list.options.listNodeName); + if (sub.length) { + item.children = step(sub, depth + 1); + } + array.push(item); + }); + return array; + }; + data = step(list.el.find(list.options.listNodeName).first(), depth); + return data; + }, + + serialise: function() + { + return this.serialize(); + }, + + 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.isTouch = false; + this.moving = false; + this.dragEl = null; + this.dragRootEl = null; + this.dragDepth = 0; + this.hasNewRoot = false; + this.pointEl = null; + }, + + expandItem: function(li) + { + li.removeClass(this.options.collapsedClass); + li.children('[data-action="expand"]').hide(); + li.children('[data-action="collapse"]').show(); + li.children(this.options.listNodeName).show(); + }, + + collapseItem: function(li) + { + var lists = li.children(this.options.listNodeName); + if (lists.length) { + li.addClass(this.options.collapsedClass); + li.children('[data-action="collapse"]').hide(); + li.children('[data-action="expand"]').show(); + li.children(this.options.listNodeName).hide(); + } + }, + + expandAll: function() + { + var list = this; + list.el.find(list.options.itemNodeName).each(function() { + list.expandItem($(this)); + }); + }, + + collapseAll: function() + { + var list = this; + list.el.find(list.options.itemNodeName).each(function() { + list.collapseItem($(this)); + }); + }, + + setParent: function(li) + { + if (li.children(this.options.listNodeName).length) { + li.prepend($(this.options.expandBtnHTML)); + li.prepend($(this.options.collapseBtnHTML)); + } + li.children('[data-action="expand"]').hide(); + }, + + unsetParent: function(li) + { + li.removeClass(this.options.collapsedClass); + li.children('[data-action]').remove(); + li.children(this.options.listNodeName).remove(); + }, + + dragStart: function(e) + { + var mouse = this.mouse, + target = $(e.target), + dragItem = target.closest(this.options.itemNodeName); + + this.placeEl.css('height', dragItem.height()); + + mouse.offsetX = e.offsetX !== undefined ? e.offsetX : e.pageX - target.offset().left; + mouse.offsetY = e.offsetY !== undefined ? e.offsetY : e.pageY - target.offset().top; + mouse.startX = mouse.lastX = e.pageX; + mouse.startY = mouse.lastY = e.pageY; + + this.dragRootEl = this.el; + + this.dragEl = $(document.createElement(this.options.listNodeName)).addClass(this.options.listClass + ' ' + this.options.dragClass); + this.dragEl.css('width', dragItem.width()); + + dragItem.after(this.placeEl); + dragItem[0].parentNode.removeChild(dragItem[0]); + dragItem.appendTo(this.dragEl); + + $(document.body).append(this.dragEl); + this.dragEl.css({ + 'left' : e.pageX - mouse.offsetX, + 'top' : e.pageY - mouse.offsetY + }); + // total depth of dragging item + var i, depth, + items = this.dragEl.find(this.options.itemNodeName); + for (i = 0; i < items.length; i++) { + depth = $(items[i]).parents(this.options.listNodeName).length; + if (depth > this.dragDepth) { + this.dragDepth = depth; + } + } + }, + + dragStop: function(e) + { + var el = this.dragEl.children(this.options.itemNodeName).first(); + el[0].parentNode.removeChild(el[0]); + this.placeEl.replaceWith(el); + + this.dragEl.remove(); + this.el.trigger('change'); + if (this.hasNewRoot) { + this.dragRootEl.trigger('change'); + } + this.reset(); + }, + + dragMove: function(e) + { + var list, parent, prev, next, depth, + opt = this.options, + mouse = this.mouse; + + 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(opt.itemNodeName); + // increase horizontal level if previous sibling exists and is not collapsed + if (mouse.distX > 0 && prev.length && !prev.hasClass(opt.collapsedClass)) { + // cannot increase level when item above is collapsed + list = prev.find(opt.listNodeName).last(); + // check if depth limit has reached + depth = this.placeEl.parents(opt.listNodeName).length; + if (depth + this.dragDepth <= opt.maxDepth) { + // create new sub-level if one doesn't exist + if (!list.length) { + list = $('<' + opt.listNodeName + '/>').addClass(opt.listClass); + list.append(this.placeEl); + prev.append(list); + this.setParent(prev); + } else { + // else append to next level up + list = prev.children(opt.listNodeName).last(); + list.append(this.placeEl); + } + } + } + // decrease horizontal level + if (mouse.distX < 0) { + // we can't decrease a level if an item preceeds the current one + next = this.placeEl.next(opt.itemNodeName); + if (!next.length) { + parent = this.placeEl.parent(); + this.placeEl.closest(opt.itemNodeName).after(this.placeEl); + if (!parent.children().length) { + this.unsetParent(parent.parent()); + } + } + } + } + + var isEmpty = false; + + // find list item under cursor + if (!hasPointerEvents) { + this.dragEl[0].style.visibility = 'hidden'; + } + this.pointEl = $(document.elementFromPoint(e.pageX - document.body.scrollLeft, e.pageY - (window.pageYOffset || document.documentElement.scrollTop))); + if (!hasPointerEvents) { + this.dragEl[0].style.visibility = 'visible'; + } + if (this.pointEl.hasClass(opt.handleClass)) { + this.pointEl = this.pointEl.parent(opt.itemNodeName); + } + if (this.pointEl.hasClass(opt.emptyClass)) { + isEmpty = true; + } + else if (!this.pointEl.length || !this.pointEl.hasClass(opt.itemClass)) { + return; + } + + // find parent list of item under cursor + var pointElRoot = this.pointEl.closest('.' + opt.rootClass), + isNewRoot = this.dragRootEl.data('nestable-id') !== pointElRoot.data('nestable-id'); + + /** + * move vertical + */ + if (!mouse.dirAx || isNewRoot || isEmpty) { + // check if groups match if dragging over new root + if (isNewRoot && opt.group !== pointElRoot.data('nestable-group')) { + return; + } + // check depth limit + depth = this.dragDepth - 1 + this.pointEl.parents(opt.listNodeName).length; + if (depth > opt.maxDepth) { + return; + } + var before = e.pageY < (this.pointEl.offset().top + this.pointEl.height() / 2); + parent = this.placeEl.parent(); + // if empty create new list to replace empty placeholder + if (isEmpty) { + list = $(document.createElement(opt.listNodeName)).addClass(opt.listClass); + list.append(this.placeEl); + this.pointEl.replaceWith(list); + } + else if (before) { + this.pointEl.before(this.placeEl); + } + else { + this.pointEl.after(this.placeEl); + } + if (!parent.children().length) { + this.unsetParent(parent.parent()); + } + if (!this.dragRootEl.find(opt.itemNodeName).length) { + this.dragRootEl.append('
'); + } + // parent root list has changed + if (isNewRoot) { + this.dragRootEl = pointElRoot; + this.hasNewRoot = this.el[0] !== this.dragRootEl[0]; + } + } + } + + }; + + $.fn.nestable = function(params) + { + var lists = this, + retval = this; + + lists.each(function() + { + var plugin = $(this).data("nestable"); + + if (!plugin) { + $(this).data("nestable", new Plugin(this, params)); + $(this).data("nestable-id", new Date().getTime()); + } else { + if (typeof params === 'string' && typeof plugin[params] === 'function') { + retval = plugin[params](); + } + } + }); + + return retval || lists; + }; })(window.jQuery || window.Zepto, window, document); From 05f1919bd9ba4f2a71ae577c8abddf7323dc3502 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 6 May 2015 21:47:08 +0900 Subject: [PATCH 22/26] file name change (to the original file name) --- jquery.nestable.withCallbacks.js => jquery.nestable.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jquery.nestable.withCallbacks.js => jquery.nestable.js (100%) diff --git a/jquery.nestable.withCallbacks.js b/jquery.nestable.js similarity index 100% rename from jquery.nestable.withCallbacks.js rename to jquery.nestable.js From d917aeb4a20871448bf7789f31277bde10dced81 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Wed, 6 May 2015 22:00:37 +0900 Subject: [PATCH 23/26] Event name changed: dragJustBeforeStart now beforeDragStart to be in line with other event names --- jquery.nestable.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jquery.nestable.js b/jquery.nestable.js index 3226fad..b1d4fb4 100644 --- a/jquery.nestable.js +++ b/jquery.nestable.js @@ -5,7 +5,7 @@ * Modified : * Added a few callbacks * afterInit - * dragJustBeforeStart + * beforeDragStart * dragStart * beforeDragEnd * dragEnd @@ -99,8 +99,8 @@ { var handle = $(e.target); - /* callback for dragJustBeforeStart */ - list.el.trigger('dragJustBeforeStart', [handle]); + /* callback for beforeDragStart */ + list.el.trigger('beforeDragStart', [handle]); if (!handle.hasClass(list.options.handleClass)) { if (handle.closest('.' + list.options.noDragClass).length) { From 7c22c1e4ae335dcea880abc80ec2981e3c0f2c67 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 9 May 2015 23:50:02 +0900 Subject: [PATCH 24/26] correction thanks to bigfoot90 --- README.md | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index eb3810f..10404d5 100644 --- a/README.md +++ b/README.md @@ -8,32 +8,34 @@ Original can be found here: https://github.com/dbushell/Nestable ## Example ``` $('#example-list-element').nestable({ - afterInit: function ( event ) { - console.log( event ); - } + afterInit: function ( event ) { + console.log( event ); + } }) -.on('dragJustBeforeStart', function(handle) { - console.log('dragStart', handle); +.on('beforeDragStart', function(handle) { + console.log('dragStart', handle); }) .on('dragStart', function(event, item, source) { - console.log('dragStart', event, item, source); + console.log('dragStart', event, item, source); +}) +.on('dragMove', function(event, item, source, destination) { + console.log('dragMove', event, item, source); }) .on('dragEnd', function(event, item, source, destination) { - console.log('dragEnd', event, item, source, destination); + console.log('dragEnd', event, item, source, destination); }) .on('beforeDragEnd', function(event, item, source, destination, position, feedback) { - if (source[0] === destination[0]) return; - feedback.abort = !window.confirm('Continue?'); + // If you need to persist list items order if changes, you need to comment the next line + if (source[0] === destination[0]) { feedback.abort = true; return; } + + feedback.abort = !window.confirm('Continue?'); }) .on('dragEnd', function(event, item, source, destination, position) { - if (source[0] === destination[0]) return; + // Make an ajax request to persist move on database + // here you can pass item-id, source-id, destination-id and position index to the server + // .... - // Make an ajax request to persist move on database - // here i need to pass item-id, source-id, destination-id, position index to the server - // .... -}) -.on('dragMove', function(event, item, source, destination) { - console.log('dragMove', event, item, source); + console.log('dragEnd', event, item, source, destination, position); }); ``` * * * From 5bf3ad5e34ed1403ec5073ce027c8ca2844c4b88 Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sat, 9 May 2015 23:58:48 +0900 Subject: [PATCH 25/26] beforeDragStart returns same params as dragStart upon suggestion by bigfoot90 See https://github.com/dbushell/Nestable/pull/143#issuecomment-99998613 --- jquery.nestable.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jquery.nestable.js b/jquery.nestable.js index b1d4fb4..e40e31c 100644 --- a/jquery.nestable.js +++ b/jquery.nestable.js @@ -100,7 +100,10 @@ var handle = $(e.target); /* callback for beforeDragStart */ - list.el.trigger('beforeDragStart', [handle]); + list.el.trigger('beforeDragStart', [ + item, // List item + list.el // Source list + ]); if (!handle.hasClass(list.options.handleClass)) { if (handle.closest('.' + list.options.noDragClass).length) { From b6d63e485b3362ecfad17032fc8f91a4bcd2227b Mon Sep 17 00:00:00 2001 From: "BeFive.INFO" Date: Sun, 10 May 2015 00:10:17 +0900 Subject: [PATCH 26/26] Reverted the beforeDragStart parameter --- jquery.nestable.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/jquery.nestable.js b/jquery.nestable.js index e40e31c..b1d4fb4 100644 --- a/jquery.nestable.js +++ b/jquery.nestable.js @@ -100,10 +100,7 @@ var handle = $(e.target); /* callback for beforeDragStart */ - list.el.trigger('beforeDragStart', [ - item, // List item - list.el // Source list - ]); + list.el.trigger('beforeDragStart', [handle]); if (!handle.hasClass(list.options.handleClass)) { if (handle.closest('.' + list.options.noDragClass).length) {