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

Commit 95422b1

Browse files
committed
Merge pull request #65 from thgreasi/angular1.2
Closes #62 and possibly #47
2 parents 528b932 + e6420b0 commit 95422b1

File tree

5 files changed

+166
-9
lines changed

5 files changed

+166
-9
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
bower_components/
2-
node_modules/
2+
node_modules/
3+
coverage/

bower.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
],
1818
"dependencies": {
1919
"angular": "~1.2.x",
20-
"jquery-ui": ">= 1.9",
21-
"jquery-simulate": "latest"
20+
"jquery-ui": ">= 1.9"
2221
},
2322
"devDependencies": {
24-
"angular-mocks": "~1.2.x"
23+
"angular-mocks": "~1.2.x",
24+
"jquery-simulate": "latest"
2525
}
2626
}

src/sortable.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@ angular.module('ui.sortable', [])
7777
// placeholder class was given or placeholder.element will be
7878
// undefined if a class was given (placeholder will be a string)
7979
if (placeholder && placeholder.element) {
80-
savedNodes = savedNodes.not(element.find(
81-
"." + placeholder.element()
82-
.attr('class').split(/\s+/).join('.')));
80+
// exact match with the placeholder's class attribute to handle
81+
// the case that multiple connected sortables exist and
82+
// the placehoilder option equals the class of sortable items
83+
var excludes = element.find('[class="' + placeholder.element().attr('class') + '"]');
84+
85+
savedNodes = savedNodes.not(excludes);
8386
}
8487
};
8588

@@ -120,7 +123,10 @@ angular.module('ui.sortable', [])
120123
// If the received flag hasn't be set on the item, this is a
121124
// normal sort, if dropindex is set, the item was moved, so move
122125
// the items in the list.
123-
if(!ui.item.sortable.received && ('dropindex' in ui.item.sortable) && !ui.item.sortable.isCanceled()) {
126+
if(!ui.item.sortable.received &&
127+
('dropindex' in ui.item.sortable) &&
128+
!ui.item.sortable.isCanceled()) {
129+
124130
scope.$apply(function () {
125131
ngModel.$modelValue.splice(
126132
ui.item.sortable.dropindex, 0,

test/sortable.spec.js

+140
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,76 @@ describe('uiSortable', function() {
114114
});
115115
});
116116

117+
it('should work when "placeholder" option is used', function() {
118+
inject(function($compile, $rootScope) {
119+
var element;
120+
element = $compile('<ul ui-sortable ng-model="items"><li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
121+
$rootScope.$apply(function() {
122+
$rootScope.opts = {
123+
placeholder: "sortable-item-placeholder"
124+
};
125+
$rootScope.items = ["One", "Two", "Three"];
126+
});
127+
128+
host.append(element);
129+
130+
var li = element.find(':eq(1)');
131+
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
132+
li.simulate('drag', { dy: dy });
133+
expect($rootScope.items).toEqual(["One", "Three", "Two"]);
134+
135+
li = element.find(':eq(1)');
136+
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
137+
li.simulate('drag', { dy: dy });
138+
expect($rootScope.items).toEqual(["Three", "One", "Two"]);
139+
140+
$(element).remove();
141+
});
142+
});
143+
144+
it('should work when "placeholder" option equals the class of items', function() {
145+
inject(function($compile, $rootScope) {
146+
var element;
147+
element = $compile('<ul ui-sortable ng-model="items"><li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
148+
$rootScope.$apply(function() {
149+
$rootScope.opts = {
150+
placeholder: "sortable-item"
151+
};
152+
$rootScope.items = ["One", "Two", "Three"];
153+
});
154+
155+
host.append(element);
156+
157+
var li = element.find(':eq(1)');
158+
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
159+
li.simulate('drag', { dy: dy });
160+
expect($rootScope.items).toEqual(["One", "Three", "Two"]);
161+
162+
li = element.find(':eq(1)');
163+
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
164+
li.simulate('drag', { dy: dy });
165+
expect($rootScope.items).toEqual(["Three", "One", "Two"]);
166+
167+
$(element).remove();
168+
});
169+
});
170+
171+
});
172+
173+
describe('Multiple sortables related', function() {
174+
175+
var host;
176+
177+
beforeEach(inject(function() {
178+
host = $('<div id="test-host"></div>');
179+
$('body').append(host);
180+
}));
181+
182+
afterEach(function() {
183+
host.remove();
184+
host = null;
185+
});
186+
117187
it('should update model when sorting between sortables', function() {
118188
inject(function($compile, $rootScope) {
119189
var elementTop, elementBottom;
@@ -146,6 +216,76 @@ describe('uiSortable', function() {
146216
});
147217
});
148218

219+
it('should work when "placeholder" option is used', function() {
220+
inject(function($compile, $rootScope) {
221+
var elementTop, elementBottom;
222+
elementTop = $compile('<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
223+
elementBottom = $compile('<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
224+
$rootScope.$apply(function() {
225+
$rootScope.itemsTop = ["Top One", "Top Two", "Top Three"];
226+
$rootScope.itemsBottom = ["Bottom One", "Bottom Two", "Bottom Three"];
227+
$rootScope.opts = {
228+
placeholder: "sortable-item-placeholder",
229+
connectWith: ".cross-sortable"
230+
};
231+
});
232+
233+
host.append(elementTop).append(elementBottom);
234+
235+
var li1 = elementTop.find(':eq(0)');
236+
var li2 = elementBottom.find(':eq(0)');
237+
var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top);
238+
li1.simulate('drag', { dy: dy });
239+
expect($rootScope.itemsTop).toEqual(["Top Two", "Top Three"]);
240+
expect($rootScope.itemsBottom).toEqual(["Bottom One", "Top One", "Bottom Two", "Bottom Three"]);
241+
242+
li1 = elementBottom.find(':eq(1)');
243+
li2 = elementTop.find(':eq(1)');
244+
dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top);
245+
li1.simulate('drag', { dy: dy });
246+
expect($rootScope.itemsTop).toEqual(["Top Two", "Top One", "Top Three"]);
247+
expect($rootScope.itemsBottom).toEqual(["Bottom One", "Bottom Two", "Bottom Three"]);
248+
249+
$(elementTop).remove();
250+
$(elementBottom).remove();
251+
});
252+
});
253+
254+
it('should work when "placeholder" option equals the class of items', function() {
255+
inject(function($compile, $rootScope) {
256+
var elementTop, elementBottom;
257+
elementTop = $compile('<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop"><li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
258+
elementBottom = $compile('<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom"><li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li></ul>')($rootScope);
259+
$rootScope.$apply(function() {
260+
$rootScope.itemsTop = ["Top One", "Top Two", "Top Three"];
261+
$rootScope.itemsBottom = ["Bottom One", "Bottom Two", "Bottom Three"];
262+
$rootScope.opts = {
263+
placeholder: "sortable-item",
264+
connectWith: ".cross-sortable"
265+
};
266+
});
267+
268+
host.append(elementTop).append(elementBottom);
269+
270+
var li1 = elementTop.find(':eq(0)');
271+
var li2 = elementBottom.find(':eq(0)');
272+
var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top);
273+
li1.simulate('drag', { dy: dy });
274+
expect($rootScope.itemsTop).toEqual(["Top Two", "Top Three"]);
275+
expect($rootScope.itemsBottom).toEqual(["Bottom One", "Top One", "Bottom Two", "Bottom Three"]);
276+
277+
li1 = elementBottom.find(':eq(1)');
278+
li2 = elementTop.find(':eq(1)');
279+
dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top);
280+
li1.simulate('drag', { dy: dy });
281+
expect($rootScope.itemsTop).toEqual(["Top Two", "Top One", "Top Three"]);
282+
expect($rootScope.itemsBottom).toEqual(["Bottom One", "Bottom Two", "Bottom Three"]);
283+
284+
$(elementTop).remove();
285+
$(elementBottom).remove();
286+
});
287+
});
288+
149289
});
150290

151291

test/test.conf.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,14 @@ files = [
1111
'test/*.spec.js'
1212
];
1313
singleRun = true;
14-
browsers = [ 'Chrome' ];
14+
autoWatch = false;
15+
browsers = [ 'Chrome' ];
16+
17+
if (singleRun) {
18+
reporters = [ 'coverage' ];
19+
preprocessors = { '**/src/*.js': 'coverage' };
20+
coverageReporter = {
21+
type : 'html',
22+
dir : 'coverage/'
23+
};
24+
}

0 commit comments

Comments
 (0)