Skip to content

Commit 59ec205

Browse files
committed
Add sort directive and update tests
1 parent 5b3bf5c commit 59ec205

22 files changed

+2271
-1874
lines changed

dist/select.bootstrap.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
* ui-select
33
* http://github.com/angular-ui/ui-select
4-
* Version: 0.12.1 - 2015-08-05T18:50:43.064Z
4+
* Version: 0.12.1 - 2015-08-06T11:06:02.027Z
55
* License: MIT
66
*/
77

@@ -588,7 +588,6 @@ uis.controller('uiSelectCtrl',
588588
* @return {boolean} true if the item is disabled
589589
*/
590590
ctrl.isDisabled = function (itemScope) {
591-
592591
if (!ctrl.open) {
593592
return false;
594593
}
@@ -608,7 +607,8 @@ uis.controller('uiSelectCtrl',
608607

609608

610609
/**
611-
* Selects an item
610+
* Selects an item. Calls the onBeforeSelect and onSelect callbacks
611+
* onBeforeSelect can alter or abort the selection
612612
*
613613
* Called when the user selects an item with ENTER or clicks the dropdown
614614
*/
@@ -648,6 +648,12 @@ uis.controller('uiSelectCtrl',
648648
}
649649
};
650650

651+
// If there's no onBeforeSelect callback, then just call the completeCallback
652+
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
653+
completeCallback(item);
654+
return;
655+
}
656+
651657
// Call the onBeforeSelect callback
652658
// Allowable responses are -:
653659
// falsy: Abort the selection
@@ -658,11 +664,15 @@ uis.controller('uiSelectCtrl',
658664
if (angular.isDefined(result)) {
659665
if (angular.isFunction(result.then)) {
660666
// Promise returned - wait for it to complete before completing the selection
661-
result.then(function (result) {
662-
if (!result) {
667+
result.then(function (response) {
668+
if (!response) {
663669
return;
664670
}
665-
completeCallback(result);
671+
if (response === true) {
672+
completeCallback(item);
673+
} else if (response) {
674+
completeCallback(response);
675+
}
666676
});
667677
} else if (result === true) {
668678
completeCallback(item);
@@ -914,8 +924,8 @@ uis.controller('uiSelectCtrl',
914924
}]);
915925

916926
uis.directive('uiSelect',
917-
['$document', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout',
918-
function ($document, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) {
927+
['$document', '$window', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout',
928+
function ($document, $window, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) {
919929

920930
return {
921931
restrict: 'EA',
@@ -1162,9 +1172,7 @@ uis.directive('uiSelect',
11621172
var offsetDropdown = uisOffset(dropdown);
11631173

11641174
// Determine if the direction of the dropdown needs to be changed.
1165-
if (offset.top + offset.height + offsetDropdown.height >
1166-
$document[0].documentElement.scrollTop +
1167-
$document[0].documentElement.clientHeight) {
1175+
if (offset.top + offset.height + offsetDropdown.height > $window.pageYOffset + $document[0].documentElement.clientHeight) {
11681176
element.addClass(directionUpClassName);
11691177
}
11701178

@@ -1263,11 +1271,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr', '$timeout', function (uiSel
12631271
ctrl.activeMatchIndex = -1;
12641272
$select.sizeSearchInput();
12651273

1266-
// If there's no onBeforeRemove callback, then we're done
1267-
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
1268-
return;
1269-
}
1270-
12711274
var callbackContext = {
12721275
$item: removedChoice,
12731276
$model: $select.parserResult.modelMapper($scope, locals)
@@ -1282,6 +1285,12 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr', '$timeout', function (uiSel
12821285
ctrl.updateModel();
12831286
}
12841287

1288+
// If there's no onBeforeRemove callback, then just call the completeCallback
1289+
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
1290+
completeCallback();
1291+
return;
1292+
}
1293+
12851294
// Call the onBeforeRemove callback
12861295
// Allowable responses are -:
12871296
// falsy: Abort the removal

dist/select.bootstrap.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/select.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
* ui-select
33
* http://github.com/angular-ui/ui-select
4-
* Version: 0.12.1 - 2015-08-05T18:50:43.115Z
4+
* Version: 0.12.1 - 2015-08-06T11:06:02.064Z
55
* License: MIT
66
*/
77

dist/select.js

Lines changed: 170 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,156 @@
11
/*!
22
* ui-select
33
* http://github.com/angular-ui/ui-select
4-
* Version: 0.12.1 - 2015-08-05T18:50:43.112Z
4+
* Version: 0.12.1 - 2015-08-06T11:06:02.062Z
55
* License: MIT
66
*/
77

88

9+
(function () {
10+
"use strict";
11+
// Make multiple matches sortable
12+
angular.module('ui.select.sort', ['ui.select'])
13+
.directive('uiSelectSort',
14+
['$timeout', 'uiSelectConfig', 'uiSelectMinErr', function ($timeout, uiSelectConfig, uiSelectMinErr) {
15+
return {
16+
require: '^uiSelect',
17+
link: function (scope, element, attrs, $select) {
18+
if (scope[attrs.uiSelectSort] === null) {
19+
throw uiSelectMinErr('sort', "Expected a list to sort");
20+
}
21+
22+
var options = angular.extend({
23+
axis: 'horizontal'
24+
},
25+
scope.$eval(attrs.uiSelectSortOptions));
26+
27+
var axis = options.axis,
28+
draggingClassName = 'dragging',
29+
droppingClassName = 'dropping',
30+
droppingBeforeClassName = 'dropping-before',
31+
droppingAfterClassName = 'dropping-after';
32+
33+
scope.$watch(function () {
34+
return $select.sortable;
35+
}, function (n) {
36+
if (n) {
37+
element.attr('draggable', true);
38+
} else {
39+
element.removeAttr('draggable');
40+
}
41+
});
42+
43+
element.on('dragstart', function (e) {
44+
element.addClass(draggingClassName);
45+
46+
(e.dataTransfer || e.originalEvent.dataTransfer).setData('text/plain', scope.$index);
47+
});
48+
49+
element.on('dragend', function () {
50+
element.removeClass(draggingClassName);
51+
});
52+
53+
var move = function (from, to) {
54+
/*jshint validthis: true */
55+
this.splice(to, 0, this.splice(from, 1)[0]);
56+
};
57+
58+
var dragOverHandler = function (e) {
59+
e.preventDefault();
60+
61+
var offset = axis === 'vertical' ?
62+
e.offsetY || e.layerY || (e.originalEvent ? e.originalEvent.offsetY : 0) :
63+
e.offsetX || e.layerX || (e.originalEvent ? e.originalEvent.offsetX : 0);
64+
65+
if (offset < (this[axis === 'vertical' ? 'offsetHeight' : 'offsetWidth'] / 2)) {
66+
element.removeClass(droppingAfterClassName);
67+
element.addClass(droppingBeforeClassName);
68+
69+
} else {
70+
element.removeClass(droppingBeforeClassName);
71+
element.addClass(droppingAfterClassName);
72+
}
73+
};
74+
75+
var dropTimeout;
76+
77+
var dropHandler = function (e) {
78+
e.preventDefault();
79+
80+
var droppedItemIndex = parseInt((e.dataTransfer ||
81+
e.originalEvent.dataTransfer).getData('text/plain'), 10);
82+
83+
// prevent event firing multiple times in firefox
84+
$timeout.cancel(dropTimeout);
85+
dropTimeout = $timeout(function () {
86+
_dropHandler(droppedItemIndex);
87+
}, 20);
88+
};
89+
90+
var _dropHandler = function (droppedItemIndex) {
91+
var theList = scope.$eval(attrs.uiSelectSort),
92+
itemToMove = theList[droppedItemIndex],
93+
newIndex = null;
94+
95+
if (element.hasClass(droppingBeforeClassName)) {
96+
if (droppedItemIndex < scope.$index) {
97+
newIndex = scope.$index - 1;
98+
} else {
99+
newIndex = scope.$index;
100+
}
101+
} else {
102+
if (droppedItemIndex < scope.$index) {
103+
newIndex = scope.$index;
104+
} else {
105+
newIndex = scope.$index + 1;
106+
}
107+
}
108+
109+
move.apply(theList, [droppedItemIndex, newIndex]);
110+
111+
scope.$apply(function () {
112+
scope.$emit('uiSelectSort:change', {
113+
array: theList,
114+
item: itemToMove,
115+
from: droppedItemIndex,
116+
to: newIndex
117+
});
118+
});
119+
120+
element.removeClass(droppingClassName);
121+
element.removeClass(droppingBeforeClassName);
122+
element.removeClass(droppingAfterClassName);
123+
124+
element.off('drop', dropHandler);
125+
};
126+
127+
element.on('dragenter', function () {
128+
if (element.hasClass(draggingClassName)) {
129+
return;
130+
}
131+
132+
element.addClass(droppingClassName);
133+
134+
element.on('dragover', dragOverHandler);
135+
element.on('drop', dropHandler);
136+
});
137+
138+
element.on('dragleave', function (e) {
139+
if (e.target != element) {
140+
return;
141+
}
142+
element.removeClass(droppingClassName);
143+
element.removeClass(droppingBeforeClassName);
144+
element.removeClass(droppingAfterClassName);
145+
146+
element.off('dragover', dragOverHandler);
147+
element.off('drop', dropHandler);
148+
});
149+
}
150+
};
151+
}]);
152+
153+
}());
9154
(function () {
10155
"use strict";
11156
var KEY = {
@@ -588,7 +733,6 @@ uis.controller('uiSelectCtrl',
588733
* @return {boolean} true if the item is disabled
589734
*/
590735
ctrl.isDisabled = function (itemScope) {
591-
592736
if (!ctrl.open) {
593737
return false;
594738
}
@@ -608,7 +752,8 @@ uis.controller('uiSelectCtrl',
608752

609753

610754
/**
611-
* Selects an item
755+
* Selects an item. Calls the onBeforeSelect and onSelect callbacks
756+
* onBeforeSelect can alter or abort the selection
612757
*
613758
* Called when the user selects an item with ENTER or clicks the dropdown
614759
*/
@@ -648,6 +793,12 @@ uis.controller('uiSelectCtrl',
648793
}
649794
};
650795

796+
// If there's no onBeforeSelect callback, then just call the completeCallback
797+
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
798+
completeCallback(item);
799+
return;
800+
}
801+
651802
// Call the onBeforeSelect callback
652803
// Allowable responses are -:
653804
// falsy: Abort the selection
@@ -658,11 +809,15 @@ uis.controller('uiSelectCtrl',
658809
if (angular.isDefined(result)) {
659810
if (angular.isFunction(result.then)) {
660811
// Promise returned - wait for it to complete before completing the selection
661-
result.then(function (result) {
662-
if (!result) {
812+
result.then(function (response) {
813+
if (!response) {
663814
return;
664815
}
665-
completeCallback(result);
816+
if (response === true) {
817+
completeCallback(item);
818+
} else if (response) {
819+
completeCallback(response);
820+
}
666821
});
667822
} else if (result === true) {
668823
completeCallback(item);
@@ -914,8 +1069,8 @@ uis.controller('uiSelectCtrl',
9141069
}]);
9151070

9161071
uis.directive('uiSelect',
917-
['$document', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout',
918-
function ($document, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) {
1072+
['$document', '$window', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout',
1073+
function ($document, $window, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) {
9191074

9201075
return {
9211076
restrict: 'EA',
@@ -1162,9 +1317,7 @@ uis.directive('uiSelect',
11621317
var offsetDropdown = uisOffset(dropdown);
11631318

11641319
// Determine if the direction of the dropdown needs to be changed.
1165-
if (offset.top + offset.height + offsetDropdown.height >
1166-
$document[0].documentElement.scrollTop +
1167-
$document[0].documentElement.clientHeight) {
1320+
if (offset.top + offset.height + offsetDropdown.height > $window.pageYOffset + $document[0].documentElement.clientHeight) {
11681321
element.addClass(directionUpClassName);
11691322
}
11701323

@@ -1263,11 +1416,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr', '$timeout', function (uiSel
12631416
ctrl.activeMatchIndex = -1;
12641417
$select.sizeSearchInput();
12651418

1266-
// If there's no onBeforeRemove callback, then we're done
1267-
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
1268-
return;
1269-
}
1270-
12711419
var callbackContext = {
12721420
$item: removedChoice,
12731421
$model: $select.parserResult.modelMapper($scope, locals)
@@ -1282,6 +1430,12 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr', '$timeout', function (uiSel
12821430
ctrl.updateModel();
12831431
}
12841432

1433+
// If there's no onBeforeRemove callback, then just call the completeCallback
1434+
if(!angular.isDefined(ctrl.onBeforeRemoveCallback)) {
1435+
completeCallback();
1436+
return;
1437+
}
1438+
12851439
// Call the onBeforeRemove callback
12861440
// Allowable responses are -:
12871441
// falsy: Abort the removal

dist/select.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/select.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)