diff --git a/src/sortable.js b/src/sortable.js
index 94077dc..ffc27ea 100644
--- a/src/sortable.js
+++ b/src/sortable.js
@@ -63,7 +63,20 @@ angular.module('ui.sortable', [])
ui.item.sortable._destroy();
}
- var opts = {};
+ // return the index of ui.item among the items
+ // we can't just do ui.item.index() because there it might have siblings
+ // which are not items
+ function getItemIndex(ui) {
+ return ui.item.parent().find('> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]')
+ .index(ui.item);
+ }
+
+ var opts = {
+ // the default for jquery-ui sortable is "> *", we need to restrict this to
+ // ng-repeat items
+ // if the user uses
+ items: '> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]'
+ };
// directive specific options
var directiveOpts = {
@@ -114,9 +127,10 @@ angular.module('ui.sortable', [])
}
// Save the starting position of dragged item
+ var index = getItemIndex(ui);
ui.item.sortable = {
- model: ngModel.$modelValue[ui.item.index()],
- index: ui.item.index(),
+ model: ngModel.$modelValue[index],
+ index: index,
source: ui.item.parent(),
sourceModel: ngModel.$modelValue,
cancel: function () {
@@ -184,7 +198,7 @@ angular.module('ui.sortable', [])
// update that happens when moving between lists because then
// the value will be overwritten with the old value
if(!ui.item.sortable.received) {
- ui.item.sortable.dropindex = ui.item.index();
+ ui.item.sortable.dropindex = getItemIndex(ui);
var droptarget = ui.item.parent();
ui.item.sortable.droptarget = droptarget;
@@ -325,6 +339,10 @@ angular.module('ui.sortable', [])
value = wrappers[key](value);
}
+ if (key === 'items' && !value) {
+ value = '> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]';
+ }
+
opts[key] = value;
element.sortable('option', key, value);
});
diff --git a/test/sortable.e2e.extraElements.spec.js b/test/sortable.e2e.extraElements.spec.js
new file mode 100644
index 0000000..1589c5b
--- /dev/null
+++ b/test/sortable.e2e.extraElements.spec.js
@@ -0,0 +1,716 @@
+'use strict';
+
+describe('uiSortable', function() {
+
+ beforeEach(module(function($compileProvider) {
+ if (typeof $compileProvider.debugInfoEnabled === 'function') {
+ $compileProvider.debugInfoEnabled(false);
+ }
+ }));
+
+ // Ensure the sortable angular module is loaded
+ beforeEach(module('ui.sortable'));
+ beforeEach(module('ui.sortable.testHelper'));
+
+ var EXTRA_DY_PERCENTAGE, listContent, listInnerContent;
+
+ beforeEach(inject(function (sortableTestHelper) {
+ EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
+ listContent = sortableTestHelper.listContent;
+ listInnerContent = sortableTestHelper.listInnerContent;
+ }));
+
+ describe('Drag & Drop simulation, when there are extra elements', function() {
+
+ var host;
+
+ beforeEach(inject(function() {
+ host = $('
');
+ $('body').append(host);
+ }));
+
+ afterEach(function() {
+ host.remove();
+ host = null;
+ });
+
+ it('should update model when order changes', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(2)');
+ 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 not allow sorting of "locked" nodes', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item.text }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ items:'> .sortable'
+ };
+ $rootScope.items = [
+ { text: 'One', sortable: true },
+ { text: 'Two', sortable: true },
+ { text: 'Three', sortable: false },
+ { text: 'Four', sortable: true }
+ ];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(3)');
+ var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.simulate('drag', { dy: dy });
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['One', 'Two', 'Three', 'Four']);
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(listContent(element));
+
+ li = element.find(':eq(2)');
+ dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.simulate('drag', { dy: dy });
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['One', 'Three', 'Four', 'Two']);
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(listContent(element));
+
+ li = element.find(':eq(3)');
+ dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.simulate('drag', { dy: dy });
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['Four', 'One', 'Three', 'Two']);
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(listContent(element));
+
+ li = element.find(':eq(4)');
+ dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.simulate('drag', { dy: dy });
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['Four', 'Two', 'One', 'Three']);
+ expect($rootScope.items.map(function(x){ return x.text; })).toEqual(listContent(element));
+
+ // also placing right above the locked node seems a bit harder !?!?
+
+ $(element).remove();
+ });
+ });
+
+ it('should work when "placeholder" option is used', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ placeholder: 'sortable-item-placeholder'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(2)');
+ 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 "placeholder" option equals the class of items', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ placeholder: 'sortable-item'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(2)');
+ 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 "placeholder" option equals the class of items [data-ng-repeat]', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ placeholder: 'sortable-item'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(2)');
+ 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 continue to work after a drag is reverted', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ placeholder: 'sortable-item'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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 "handle" option is used', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- H {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ handle: '.handle'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find('li:eq(2)');
+ var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(2)');
+ dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ $(element).remove();
+ });
+ });
+
+ it('should properly remove elements after a sorting', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- H {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ handle: '.handle'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+
+ $rootScope.remove = function (item, itemIndex) {
+ $rootScope.items.splice(itemIndex, 1);
+ };
+ });
+
+ host.append(element);
+
+ var li = element.find('li:eq(2)');
+ var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(2)');
+ li.find('.removeButton').click();
+ expect($rootScope.items).toEqual(['One', 'Two']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(1)');
+ dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['Two', 'One']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(1)');
+ li.find('.removeButton').click();
+ expect($rootScope.items).toEqual(['One']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ $(element).remove();
+ });
+ });
+
+ it('should properly remove elements after a drag is reverted', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- H {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ handle: '.handle'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+
+ $rootScope.remove = function (item, itemIndex) {
+ $rootScope.items.splice(itemIndex, 1);
+ };
+ });
+
+ host.append(element);
+
+ var li = element.find('li:eq(1)');
+ var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('dragAndRevert', { dy: dy });
+ expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(1)');
+ li.find('.removeButton').click();
+ expect($rootScope.items).toEqual(['Two', 'Three']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ li = element.find('li:eq(1)');
+ dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.find('.handle').simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['Three', 'Two']);
+ expect($rootScope.items).toEqual(listInnerContent(element));
+
+ $(element).remove();
+ });
+ });
+
+ it('should work when "helper: clone" option is used', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: 'clone'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(2)');
+ 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: clone" option is used and a drag is reverted', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: 'clone'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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: clone" and "appendTo" options are used together', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: 'clone',
+ appendTo: 'body'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(2)');
+ 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(3)');
+ dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
+ li.simulate('drag', { dy: dy });
+ expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
+ expect($rootScope.items).toEqual(listContent(element));
+
+ $(element).remove();
+ });
+ });
+
+ it('should work when "helper: clone" and "placeholder" options are used together.', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: 'clone',
+ placeholder: 'sortable-item'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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(2)');
+ 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" option is used', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($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(2)');
+ 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(2)');
+ 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('- extra element
- {{ item }}
- extra element
')($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 = (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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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('- extra element
- {{ item }}
- extra element
')($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(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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(2)');
+ 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" that returns a list element is used', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: function (e, item) {
+ return item;
+ }
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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" that returns a list element and "placeholder" options are used together.', function() {
+ inject(function($compile, $rootScope) {
+ var element;
+ element = $compile('- extra element
- {{ item }}
- extra element
')($rootScope);
+ $rootScope.$apply(function() {
+ $rootScope.opts = {
+ helper: function (e, item) {
+ return item;
+ },
+ placeholder: 'sortable-item'
+ };
+ $rootScope.items = ['One', 'Two', 'Three'];
+ });
+
+ host.append(element);
+
+ var li = element.find(':eq(1)');
+ 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(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));
+
+ li = element.find(':eq(2)');
+ 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(2)');
+ 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(2)');
+ 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();
+ });
+ });
+
+ });
+
+});
diff --git a/test/sortable.spec.js b/test/sortable.spec.js
index fd664bd..3ce0348 100644
--- a/test/sortable.spec.js
+++ b/test/sortable.spec.js
@@ -179,6 +179,95 @@ describe('uiSortable', function() {
});
});
+ describe('items option', function() {
+
+ it('should use a default items that is restricted to ng-repeat items', function() {
+
+ inject(function($compile, $rootScope, $timeout) {
+ var element;
+ var childScope = $rootScope.$new();
+ element = $compile('')(childScope);
+
+ $rootScope.$digest();
+
+ expect(element.find('ul').sortable('option', 'items')).toBe('> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]');
+
+ element.remove(element.firstChild);
+
+ expect(function() {
+ $timeout.flush();
+ }).not.toThrow();
+
+ });
+
+ });
+
+ it('should not change items option if given', function() {
+
+ inject(function($compile, $rootScope, $timeout) {
+ var element;
+ var childScope = $rootScope.$new();
+ childScope.opts = {
+ items: '> .class'
+ };
+
+ element = $compile('')(childScope);
+
+ $rootScope.$digest();
+
+ expect(element.find('ul').sortable('option', 'items')).toBe('> .class');
+
+ element.remove(element.firstChild);
+
+ expect(function() {
+ $timeout.flush();
+ }).not.toThrow();
+
+ });
+
+ });
+
+ it('should restrict to ng-items if items is removed after initialization', function() {
+
+ inject(function($compile, $rootScope, $timeout) {
+ var element;
+ var childScope = $rootScope.$new();
+ childScope.opts = {
+ items: '> .class'
+ };
+
+ element = $compile('')(childScope);
+
+ $rootScope.$digest();
+
+ $rootScope.$apply(function() {
+ childScope.opts = { items: null };
+ });
+
+ expect(element.find('ul').sortable('option', 'items')).toBe('> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]');
+
+ element.remove(element.firstChild);
+
+ expect(function() {
+ $timeout.flush();
+ }).not.toThrow();
+
+ });
+
+ });
+
+
+
+
+
+
+
+ });
+
+
+
+
+
});
});
diff --git a/test/sortable.test-helper.js b/test/sortable.test-helper.js
index 5728d49..8cae026 100644
--- a/test/sortable.test-helper.js
+++ b/test/sortable.test-helper.js
@@ -6,7 +6,7 @@ angular.module('ui.sortable.testHelper', [])
function listContent (list) {
if (list && list.length) {
- return list.children().map(function(){ return this.innerHTML; }).toArray();
+ return list.children('[ng-repeat], [data-ng-repeat], [x-ng-repeat]').map(function(){ return this.innerHTML; }).toArray();
}
return [];
}