From 050c9c1e64de2693b3cbf09d3bf11474542b5e9b Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Sun, 4 May 2014 18:36:42 +0300 Subject: [PATCH] fix(sortable): support `helper` option when set to a function --- bower.json | 2 +- package.json | 2 +- src/sortable.js | 10 ++- test/sortable.e2e.multi.spec.js | 83 +++++++++++++++++++++ test/sortable.e2e.spec.js | 124 ++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index f6ebb2c..37f1fd1 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-ui-sortable", - "version": "0.12.5", + "version": "0.12.6", "description": "This directive allows you to jQueryUI Sortable.", "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", "license": "MIT", diff --git a/package.json b/package.json index 95b3993..f5e4c51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-ui-sortable", - "version": "0.12.5", + "version": "0.12.6", "description": "This directive allows you to jQueryUI Sortable.", "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", "license": "MIT", diff --git a/src/sortable.js b/src/sortable.js index 15c27d8..2687640 100644 --- a/src/sortable.js +++ b/src/sortable.js @@ -23,6 +23,11 @@ angular.module('ui.sortable', []) return first; } + function hasSortingHelper (element) { + var helperOption = element.sortable('option','helper'); + return helperOption === 'clone' || typeof helperOption === 'function'; + } + var opts = {}; var callbacks = { @@ -120,7 +125,7 @@ angular.module('ui.sortable', []) // the start and stop of repeat sections and sortable doesn't // respect their order (even if we cancel, the order of the // comments are still messed up). - if (element.sortable('option','helper') === 'clone') { + if (hasSortingHelper(element)) { // restore all the savedNodes except .ui-sortable-helper element // (which is placed last). That way it will be garbage collected. savedNodes = savedNodes.not(savedNodes.last()); @@ -155,7 +160,8 @@ angular.module('ui.sortable', []) } else { // if the item was not moved, then restore the elements // so that the ngRepeat's comment are correct. - if((!('dropindex' in ui.item.sortable) || ui.item.sortable.isCanceled()) && element.sortable('option','helper') !== 'clone') { + if ((!('dropindex' in ui.item.sortable) || ui.item.sortable.isCanceled()) && + !hasSortingHelper(element)) { savedNodes.appendTo(element); } } diff --git a/test/sortable.e2e.multi.spec.js b/test/sortable.e2e.multi.spec.js index 43eb2ba..3a16df7 100644 --- a/test/sortable.e2e.multi.spec.js +++ b/test/sortable.e2e.multi.spec.js @@ -263,6 +263,89 @@ describe('uiSortable', function() { }); }); + it('should work when "helper: function" option is used', function() { + inject(function($compile, $rootScope) { + var elementTop, elementBottom; + elementTop = $compile('')($rootScope); + elementBottom = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three']; + $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three']; + $rootScope.opts = { + helper: function (e, item) { + return item.clone().text('helper'); + }, + connectWith: '.cross-sortable' + }; + }); + + host.append(elementTop).append(elementBottom); + + var li1 = elementTop.find(':eq(0)'); + var li2 = elementBottom.find(':eq(0)'); + var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top); + li1.simulate('drag', { dy: dy }); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Top One', 'Bottom Two', 'Bottom Three']); + expect($rootScope.itemsTop).toEqual(listContent(elementTop)); + expect($rootScope.itemsBottom).toEqual(listContent(elementBottom)); + + li1 = elementBottom.find(':eq(1)'); + li2 = elementTop.find(':eq(1)'); + dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top); + li1.simulate('drag', { dy: dy }); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Bottom Two', 'Bottom Three']); + expect($rootScope.itemsTop).toEqual(listContent(elementTop)); + expect($rootScope.itemsBottom).toEqual(listContent(elementBottom)); + + $(elementTop).remove(); + $(elementBottom).remove(); + }); + }); + + it('should work when "placeholder" and "helper: function" options are used', function() { + inject(function($compile, $rootScope) { + var elementTop, elementBottom; + elementTop = $compile('')($rootScope); + elementBottom = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three']; + $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three']; + $rootScope.opts = { + helper: function (e, item) { + return item.clone().text('helper'); + }, + placeholder: 'sortable-item-placeholder', + connectWith: '.cross-sortable' + }; + }); + + host.append(elementTop).append(elementBottom); + + var li1 = elementTop.find(':eq(0)'); + var li2 = elementBottom.find(':eq(0)'); + var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top); + li1.simulate('drag', { dy: dy }); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Top One', 'Bottom Two', 'Bottom Three']); + expect($rootScope.itemsTop).toEqual(listContent(elementTop)); + expect($rootScope.itemsBottom).toEqual(listContent(elementBottom)); + + li1 = elementBottom.find(':eq(1)'); + li2 = elementTop.find(':eq(1)'); + dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top); + li1.simulate('drag', { dy: dy }); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Bottom Two', 'Bottom Three']); + expect($rootScope.itemsTop).toEqual(listContent(elementTop)); + expect($rootScope.itemsBottom).toEqual(listContent(elementBottom)); + + $(elementTop).remove(); + $(elementBottom).remove(); + }); + }); + }); }); \ No newline at end of file diff --git a/test/sortable.e2e.spec.js b/test/sortable.e2e.spec.js index f6dc6bb..77c463a 100644 --- a/test/sortable.e2e.spec.js +++ b/test/sortable.e2e.spec.js @@ -429,6 +429,130 @@ describe('uiSortable', function() { }); }); + it('should work when "helper: function" option is used', function() { + inject(function($compile, $rootScope) { + var element; + element = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.opts = { + helper: function (e, item) { + return item.clone().text('helper'); + } + }; + $rootScope.items = ['One', 'Two', 'Three']; + }); + + host.append(element); + + var li = element.find(':eq(1)'); + var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Three', 'One', 'Two']); + expect($rootScope.items).toEqual(listContent(element)); + + $(element).remove(); + }); + }); + + it('should work when "helper: function" option is used and a drag is reverted', function() { + inject(function($compile, $rootScope) { + var element; + element = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.opts = { + helper: function (e, item) { + return item.clone().text('helper'); + } + }; + $rootScope.items = ['One', 'Two', 'Three']; + }); + + host.append(element); + + var li = element.find(':eq(0)'); + var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('dragAndRevert', { dy: dy }); + expect($rootScope.items).toEqual(['One', 'Two', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(0)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'Three', 'One']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + $(element).remove(); + }); + }); + + it('should work when "helper: function" and "placeholder" options are used together.', function() { + inject(function($compile, $rootScope) { + var element; + element = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.opts = { + helper: function (e, item) { + return item.clone().text('helper'); + }, + placeholder: 'sortable-item' + }; + $rootScope.items = ['One', 'Two', 'Three']; + }); + + host.append(element); + + var li = element.find(':eq(0)'); + var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('dragAndRevert', { dy: dy }); + expect($rootScope.items).toEqual(['One', 'Two', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(0)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'Three', 'One']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('dragAndRevert', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'Three', 'One']); + expect($rootScope.items).toEqual(listContent(element)); + + li = element.find(':eq(1)'); + dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); + li.simulate('drag', { dy: dy }); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); + expect($rootScope.items).toEqual(listContent(element)); + + $(element).remove(); + }); + }); + }); }); \ No newline at end of file