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

feat(sortable): add support for the case that debugInfo is disabled #314

Merged
merged 6 commits into from
Jan 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions src/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ angular.module('ui.sortable', [])
return {
require: '?ngModel',
scope: {
ngModel: '=ngModel',
uiSortable: '=uiSortable'
ngModel: '=',
uiSortable: '='
},
link: function(scope, element, attrs, ngModel) {
var savedNodes;
Expand Down Expand Up @@ -47,6 +47,18 @@ angular.module('ui.sortable', [])
return (/left|right/).test(item.css('float')) || (/inline|table-cell/).test(item.css('display'));
}

function getElementScope(elementScopes, element) {
var result = null;
for (var i = 0; i < elementScopes.length; i++) {
var x = elementScopes[i];
if (x.element[0] === element[0]) {
result = x.scope;
break;
}
}
return result;
}

function afterStop(e, ui) {
ui.item.sortable._destroy();
}
Expand Down Expand Up @@ -126,7 +138,7 @@ angular.module('ui.sortable', [])
};
};

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

savedNodes = savedNodes.not(excludes);
}

// save the directive's scope so that it is accessible from ui.item.sortable
var connectedSortables = ui.item.sortable._connectedSortables || [];

connectedSortables.push({
element: element,
scope: scope
});

ui.item.sortable._connectedSortables = connectedSortables;
};

callbacks.update = function(e, ui) {
Expand All @@ -165,8 +187,9 @@ angular.module('ui.sortable', [])
ui.item.sortable.dropindex = ui.item.index();
var droptarget = ui.item.parent();
ui.item.sortable.droptarget = droptarget;
var attr = droptarget.attr('ng-model') || droptarget.attr('data-ng-model');
ui.item.sortable.droptargetModel = droptarget.scope().$eval(attr);

var droptargetScope = getElementScope(ui.item.sortable._connectedSortables, droptarget);
ui.item.sortable.droptargetModel = droptargetScope.ngModel;

// Cancel the sort (let ng-repeat do the sort for us)
// Don't cancel if this is the received list because it has
Expand Down
18 changes: 12 additions & 6 deletions test/sortable.e2e.callbacks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down Expand Up @@ -35,7 +41,7 @@ describe('uiSortable', function() {
$rootScope.$apply(function() {
$rootScope.opts = {
update: function(e, ui) {
if (ui.item.scope().item === 'Two') {
if (ui.item.sortable.model === 'Two') {
ui.item.sortable.cancel();
}
}
Expand Down Expand Up @@ -77,7 +83,7 @@ describe('uiSortable', function() {
return item;
},
update: function(e, ui) {
if (ui.item.scope().item === 'Two') {
if (ui.item.sortable.model === 'Two') {
ui.item.sortable.cancel();
}
}
Expand Down Expand Up @@ -117,7 +123,7 @@ describe('uiSortable', function() {
$rootScope.$apply(function() {
$rootScope.opts = {
update: function(e, ui) {
$rootScope.logs.push('Moved element ' + ui.item.scope().item);
$rootScope.logs.push('Moved element ' + ui.item.sortable.model);
}
};
$rootScope.items = ['One', 'Two', 'Three'];
Expand Down Expand Up @@ -148,7 +154,7 @@ describe('uiSortable', function() {
$rootScope.$apply(function() {
$rootScope.opts = {
stop: function(e, ui) {
$rootScope.logs.push('Moved element ' + ui.item.scope().item);
$rootScope.logs.push('Moved element ' + ui.item.sortable.model);
}
};
$rootScope.items = ['One', 'Two', 'Three'];
Expand Down Expand Up @@ -199,7 +205,7 @@ describe('uiSortable', function() {
$rootScope.$apply(function() {
$rootScope.opts = {
update: function(e, ui) {
if (ui.item.scope().item === 'Two') {
if (ui.item.sortable.model === 'Two') {
ui.item.sortable.cancel();
}
updateCallbackExpectations(ui.item.sortable);
Expand Down Expand Up @@ -276,7 +282,7 @@ describe('uiSortable', function() {
uiItemSortable_Destroy = ui.item.sortable._destroy;
},
update: function(e, ui) {
if (ui.item.scope().item === 'Two') {
if (ui.item.sortable.model === 'Two') {
ui.item.sortable.cancel();
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/sortable.e2e.directiveoptions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down
6 changes: 6 additions & 0 deletions test/sortable.e2e.directives.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down
58 changes: 35 additions & 23 deletions test/sortable.e2e.multi.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down Expand Up @@ -68,14 +74,17 @@ describe('uiSortable', function() {
inject(function($compile, $rootScope) {
var elementTop, elementBottom,
wrapperTop, wrapperBottom,
wrapperTopScope, wrapperBottomScope,
itemsTop, itemsBottom;
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);
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);
wrapperTopScope = $rootScope.$new();
wrapperBottomScope = $rootScope.$new();
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);
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);

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

Expand Down Expand Up @@ -462,9 +471,9 @@ describe('uiSortable', function() {
$rootScope.opts = {
connectWith: '.cross-sortable',
update: function(e, ui) {
if (ui.item.scope() &&
(typeof ui.item.scope().item === 'string') &&
ui.item.scope().item.indexOf('Two') >= 0) {
if (ui.item.sortable.model &&
(typeof ui.item.sortable.model === 'string') &&
ui.item.sortable.model.indexOf('Two') >= 0) {
ui.item.sortable.cancel();
}
}
Expand Down Expand Up @@ -521,9 +530,9 @@ describe('uiSortable', function() {
$rootScope.opts = {
connectWith: '.cross-sortable',
update: function(e, ui) {
if (ui.item.scope() &&
(typeof ui.item.scope().item === 'string') &&
ui.item.scope().item.indexOf('Two') >= 0) {
if (ui.item.sortable.model &&
(typeof ui.item.sortable.model === 'string') &&
ui.item.sortable.model.indexOf('Two') >= 0) {
ui.item.sortable.cancel();
}
updateCallbackExpectations(ui.item.sortable);
Expand Down Expand Up @@ -660,9 +669,9 @@ describe('uiSortable', function() {
$rootScope.opts = {
connectWith: '.cross-sortable',
update: function(e, ui) {
if (ui.item.scope() &&
(typeof ui.item.scope().item === 'string') &&
ui.item.scope().item.indexOf('Two') >= 0) {
if (ui.item.sortable.model &&
(typeof ui.item.sortable.model === 'string') &&
ui.item.sortable.model.indexOf('Two') >= 0) {
ui.item.sortable.cancel();
}
updateCallbackExpectations(ui.item.sortable);
Expand Down Expand Up @@ -729,21 +738,24 @@ describe('uiSortable', function() {
inject(function($compile, $rootScope) {
var elementTop, elementBottom,
wrapperTop, wrapperBottom,
wrapperTopScope, wrapperBottomScope,
itemsTop, itemsBottom,
updateCallbackExpectations;
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);
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);
wrapperTopScope = $rootScope.$new();
wrapperBottomScope = $rootScope.$new();
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);
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);

host.append(wrapperTop).append(wrapperBottom).append('<div class="clear"></div>');
$rootScope.$apply(function() {
wrapperTop.scope().itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
wrapperBottom.scope().itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
wrapperTopScope.itemsTop = itemsTop = ['Top One', 'Top Two', 'Top Three'];
wrapperBottomScope.itemsBottom = itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
$rootScope.opts = {
connectWith: '.cross-sortable',
update: function(e, ui) {
if (ui.item.scope() &&
(typeof ui.item.scope().item === 'string') &&
ui.item.scope().item.indexOf('Two') >= 0) {
if (ui.item.sortable.model &&
(typeof ui.item.sortable.model === 'string') &&
ui.item.sortable.model.indexOf('Two') >= 0) {
ui.item.sortable.cancel();
}
updateCallbackExpectations(ui.item.sortable);
Expand Down Expand Up @@ -824,9 +836,9 @@ describe('uiSortable', function() {
},
update: function(e, ui) {
uiItem.sortable = ui.item.sortable;
if (ui.item.scope() &&
(typeof ui.item.scope().item === 'string') &&
ui.item.scope().item.indexOf('Two') >= 0) {
if (ui.item.sortable.model &&
(typeof ui.item.sortable.model === 'string') &&
ui.item.sortable.model.indexOf('Two') >= 0) {
ui.item.sortable.cancel();
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/sortable.e2e.nested.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down
35 changes: 35 additions & 0 deletions test/sortable.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down Expand Up @@ -160,6 +166,35 @@ describe('uiSortable', function() {
});
});

it('should work when "placeholder" option equals the class of items [data-ng-repeat]', function() {
inject(function($compile, $rootScope) {
var element;
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);
$rootScope.$apply(function() {
$rootScope.opts = {
placeholder: 'sortable-item'
};
$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 continue to work after a drag is reverted', function() {
inject(function($compile, $rootScope) {
var element;
Expand Down
6 changes: 6 additions & 0 deletions test/sortable.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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'));
Expand Down