Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Commit cf82c0b

Browse files
committed
Merge pull request #314 from thgreasi/debugInfoEnabled
feat(sortable): add support for the case that debugInfo is disabled
2 parents 7d8b77e + b6734fe commit cf82c0b

8 files changed

+135
-35
lines changed

src/sortable.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ angular.module('ui.sortable', [])
1111
return {
1212
require: '?ngModel',
1313
scope: {
14-
ngModel: '=ngModel',
15-
uiSortable: '=uiSortable'
14+
ngModel: '=',
15+
uiSortable: '='
1616
},
1717
link: function(scope, element, attrs, ngModel) {
1818
var savedNodes;
@@ -47,6 +47,18 @@ angular.module('ui.sortable', [])
4747
return (/left|right/).test(item.css('float')) || (/inline|table-cell/).test(item.css('display'));
4848
}
4949

50+
function getElementScope(elementScopes, element) {
51+
var result = null;
52+
for (var i = 0; i < elementScopes.length; i++) {
53+
var x = elementScopes[i];
54+
if (x.element[0] === element[0]) {
55+
result = x.scope;
56+
break;
57+
}
58+
}
59+
return result;
60+
}
61+
5062
function afterStop(e, ui) {
5163
ui.item.sortable._destroy();
5264
}
@@ -126,7 +138,7 @@ angular.module('ui.sortable', [])
126138
};
127139
};
128140

129-
callbacks.activate = function(/*e, ui*/) {
141+
callbacks.activate = function(e, ui) {
130142
// We need to make a copy of the current element's contents so
131143
// we can restore it after sortable has messed it up.
132144
// This is inside activate (instead of start) in order to save
@@ -151,10 +163,20 @@ angular.module('ui.sortable', [])
151163
// exact match with the placeholder's class attribute to handle
152164
// the case that multiple connected sortables exist and
153165
// the placehoilder option equals the class of sortable items
154-
var excludes = element.find('[class="' + phElement.attr('class') + '"]');
166+
var excludes = element.find('[class="' + phElement.attr('class') + '"]:not([ng-repeat], [data-ng-repeat])');
155167

156168
savedNodes = savedNodes.not(excludes);
157169
}
170+
171+
// save the directive's scope so that it is accessible from ui.item.sortable
172+
var connectedSortables = ui.item.sortable._connectedSortables || [];
173+
174+
connectedSortables.push({
175+
element: element,
176+
scope: scope
177+
});
178+
179+
ui.item.sortable._connectedSortables = connectedSortables;
158180
};
159181

160182
callbacks.update = function(e, ui) {
@@ -165,8 +187,9 @@ angular.module('ui.sortable', [])
165187
ui.item.sortable.dropindex = ui.item.index();
166188
var droptarget = ui.item.parent();
167189
ui.item.sortable.droptarget = droptarget;
168-
var attr = droptarget.attr('ng-model') || droptarget.attr('data-ng-model');
169-
ui.item.sortable.droptargetModel = droptarget.scope().$eval(attr);
190+
191+
var droptargetScope = getElementScope(ui.item.sortable._connectedSortables, droptarget);
192+
ui.item.sortable.droptargetModel = droptargetScope.ngModel;
170193

171194
// Cancel the sort (let ng-repeat do the sort for us)
172195
// Don't cancel if this is the received list because it has

test/sortable.e2e.callbacks.spec.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));
@@ -35,7 +41,7 @@ describe('uiSortable', function() {
3541
$rootScope.$apply(function() {
3642
$rootScope.opts = {
3743
update: function(e, ui) {
38-
if (ui.item.scope().item === 'Two') {
44+
if (ui.item.sortable.model === 'Two') {
3945
ui.item.sortable.cancel();
4046
}
4147
}
@@ -77,7 +83,7 @@ describe('uiSortable', function() {
7783
return item;
7884
},
7985
update: function(e, ui) {
80-
if (ui.item.scope().item === 'Two') {
86+
if (ui.item.sortable.model === 'Two') {
8187
ui.item.sortable.cancel();
8288
}
8389
}
@@ -117,7 +123,7 @@ describe('uiSortable', function() {
117123
$rootScope.$apply(function() {
118124
$rootScope.opts = {
119125
update: function(e, ui) {
120-
$rootScope.logs.push('Moved element ' + ui.item.scope().item);
126+
$rootScope.logs.push('Moved element ' + ui.item.sortable.model);
121127
}
122128
};
123129
$rootScope.items = ['One', 'Two', 'Three'];
@@ -148,7 +154,7 @@ describe('uiSortable', function() {
148154
$rootScope.$apply(function() {
149155
$rootScope.opts = {
150156
stop: function(e, ui) {
151-
$rootScope.logs.push('Moved element ' + ui.item.scope().item);
157+
$rootScope.logs.push('Moved element ' + ui.item.sortable.model);
152158
}
153159
};
154160
$rootScope.items = ['One', 'Two', 'Three'];
@@ -199,7 +205,7 @@ describe('uiSortable', function() {
199205
$rootScope.$apply(function() {
200206
$rootScope.opts = {
201207
update: function(e, ui) {
202-
if (ui.item.scope().item === 'Two') {
208+
if (ui.item.sortable.model === 'Two') {
203209
ui.item.sortable.cancel();
204210
}
205211
updateCallbackExpectations(ui.item.sortable);
@@ -276,7 +282,7 @@ describe('uiSortable', function() {
276282
uiItemSortable_Destroy = ui.item.sortable._destroy;
277283
},
278284
update: function(e, ui) {
279-
if (ui.item.scope().item === 'Two') {
285+
if (ui.item.sortable.model === 'Two') {
280286
ui.item.sortable.cancel();
281287
}
282288
}

test/sortable.e2e.directiveoptions.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));

test/sortable.e2e.directives.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));

test/sortable.e2e.multi.spec.js

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));
@@ -68,14 +74,17 @@ describe('uiSortable', function() {
6874
inject(function($compile, $rootScope) {
6975
var elementTop, elementBottom,
7076
wrapperTop, wrapperBottom,
77+
wrapperTopScope, wrapperBottomScope,
7178
itemsTop, itemsBottom;
72-
wrapperTop = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li></ul></div>')($rootScope);
73-
wrapperBottom = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li></ul></div>')($rootScope);
79+
wrapperTopScope = $rootScope.$new();
80+
wrapperBottomScope = $rootScope.$new();
81+
wrapperTop = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li></ul></div>')(wrapperTopScope);
82+
wrapperBottom = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li></ul></div>')(wrapperBottomScope);
7483

7584
host.append(wrapperTop).append(wrapperBottom).append('<div class="clear"></div>');
7685
$rootScope.$apply(function() {
77-
wrapperTop.scope().itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
78-
wrapperBottom.scope().itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
86+
wrapperTopScope.itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
87+
wrapperBottomScope.itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
7988
$rootScope.opts = { connectWith: '.cross-sortable' };
8089
});
8190

@@ -462,9 +471,9 @@ describe('uiSortable', function() {
462471
$rootScope.opts = {
463472
connectWith: '.cross-sortable',
464473
update: function(e, ui) {
465-
if (ui.item.scope() &&
466-
(typeof ui.item.scope().item === 'string') &&
467-
ui.item.scope().item.indexOf('Two') >= 0) {
474+
if (ui.item.sortable.model &&
475+
(typeof ui.item.sortable.model === 'string') &&
476+
ui.item.sortable.model.indexOf('Two') >= 0) {
468477
ui.item.sortable.cancel();
469478
}
470479
}
@@ -521,9 +530,9 @@ describe('uiSortable', function() {
521530
$rootScope.opts = {
522531
connectWith: '.cross-sortable',
523532
update: function(e, ui) {
524-
if (ui.item.scope() &&
525-
(typeof ui.item.scope().item === 'string') &&
526-
ui.item.scope().item.indexOf('Two') >= 0) {
533+
if (ui.item.sortable.model &&
534+
(typeof ui.item.sortable.model === 'string') &&
535+
ui.item.sortable.model.indexOf('Two') >= 0) {
527536
ui.item.sortable.cancel();
528537
}
529538
updateCallbackExpectations(ui.item.sortable);
@@ -660,9 +669,9 @@ describe('uiSortable', function() {
660669
$rootScope.opts = {
661670
connectWith: '.cross-sortable',
662671
update: function(e, ui) {
663-
if (ui.item.scope() &&
664-
(typeof ui.item.scope().item === 'string') &&
665-
ui.item.scope().item.indexOf('Two') >= 0) {
672+
if (ui.item.sortable.model &&
673+
(typeof ui.item.sortable.model === 'string') &&
674+
ui.item.sortable.model.indexOf('Two') >= 0) {
666675
ui.item.sortable.cancel();
667676
}
668677
updateCallbackExpectations(ui.item.sortable);
@@ -729,21 +738,24 @@ describe('uiSortable', function() {
729738
inject(function($compile, $rootScope) {
730739
var elementTop, elementBottom,
731740
wrapperTop, wrapperBottom,
741+
wrapperTopScope, wrapperBottomScope,
732742
itemsTop, itemsBottom,
733743
updateCallbackExpectations;
734-
wrapperTop = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li></ul></div>')($rootScope);
735-
wrapperBottom = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li></ul></div>')($rootScope);
744+
wrapperTopScope = $rootScope.$new();
745+
wrapperBottomScope = $rootScope.$new();
746+
wrapperTop = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li></ul></div>')(wrapperTopScope);
747+
wrapperBottom = $compile('<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li></ul></div>')(wrapperBottomScope);
736748

737749
host.append(wrapperTop).append(wrapperBottom).append('<div class="clear"></div>');
738750
$rootScope.$apply(function() {
739-
wrapperTop.scope().itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
740-
wrapperBottom.scope().itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
751+
wrapperTopScope.itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
752+
wrapperBottomScope.itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
741753
$rootScope.opts = {
742754
connectWith: '.cross-sortable',
743755
update: function(e, ui) {
744-
if (ui.item.scope() &&
745-
(typeof ui.item.scope().item === 'string') &&
746-
ui.item.scope().item.indexOf('Two') >= 0) {
756+
if (ui.item.sortable.model &&
757+
(typeof ui.item.sortable.model === 'string') &&
758+
ui.item.sortable.model.indexOf('Two') >= 0) {
747759
ui.item.sortable.cancel();
748760
}
749761
updateCallbackExpectations(ui.item.sortable);
@@ -824,9 +836,9 @@ describe('uiSortable', function() {
824836
},
825837
update: function(e, ui) {
826838
uiItem.sortable = ui.item.sortable;
827-
if (ui.item.scope() &&
828-
(typeof ui.item.scope().item === 'string') &&
829-
ui.item.scope().item.indexOf('Two') >= 0) {
839+
if (ui.item.sortable.model &&
840+
(typeof ui.item.sortable.model === 'string') &&
841+
ui.item.sortable.model.indexOf('Two') >= 0) {
830842
ui.item.sortable.cancel();
831843
}
832844
}

test/sortable.e2e.nested.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));

test/sortable.e2e.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));
@@ -160,6 +166,35 @@ describe('uiSortable', function() {
160166
});
161167
});
162168

169+
it('should work when "placeholder" option equals the class of items [data-ng-repeat]', function() {
170+
inject(function($compile, $rootScope) {
171+
var element;
172+
element = $compile('<ul ui-sortable="opts" ng-model="items"><li data-ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
173+
$rootScope.$apply(function() {
174+
$rootScope.opts = {
175+
placeholder: 'sortable-item'
176+
};
177+
$rootScope.items = ['One', 'Two', 'Three'];
178+
});
179+
180+
host.append(element);
181+
182+
var li = element.find(':eq(1)');
183+
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
184+
li.simulate('drag', { dy: dy });
185+
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
186+
expect($rootScope.items).toEqual(listContent(element));
187+
188+
li = element.find(':eq(1)');
189+
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
190+
li.simulate('drag', { dy: dy });
191+
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
192+
expect($rootScope.items).toEqual(listContent(element));
193+
194+
$(element).remove();
195+
});
196+
});
197+
163198
it('should continue to work after a drag is reverted', function() {
164199
inject(function($compile, $rootScope) {
165200
var element;

test/sortable.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
describe('uiSortable', function() {
44

5+
beforeEach(module(function($compileProvider) {
6+
if (typeof $compileProvider.debugInfoEnabled === 'function') {
7+
$compileProvider.debugInfoEnabled(false);
8+
}
9+
}));
10+
511
// Ensure the sortable angular module is loaded
612
beforeEach(module('ui.sortable'));
713
beforeEach(module('ui.sortable.testHelper'));

0 commit comments

Comments
 (0)