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

Commit 37c11b9

Browse files
committed
Merge pull request #280 from angular-ui/v0.13.x-dev
chore: merge V0.13.x dev into master
2 parents 57c5332 + c819182 commit 37c11b9

10 files changed

+690
-13
lines changed

API.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# ui.item.sortable API documentation
2+
3+
## Properties
4+
5+
### dropindex
6+
Type: [Integer](http://api.jquery.com/Types/#Integer)
7+
Holds the index of the drop target that the dragged item was dropped.
8+
9+
10+
### droptarget
11+
Type: [jQuery](http://api.jquery.com/Types/#jQuery)
12+
Holds the ui-sortable element that the dragged item was dropped on.
13+
14+
### droptargetModel
15+
Type: [Array](http://api.jquery.com/Types/#Array)
16+
Holds the array that is specified by the `ng-model` attribute of the [`droptarget`](#droptarget) ui-sortable element.
17+
18+
### index
19+
Type: [Integer](http://api.jquery.com/Types/#Integer)
20+
Holds the original index of the item dragged.
21+
22+
### model
23+
Type: [Object](http://api.jquery.com/Types/#Object)
24+
Holds the JavaScript object that is used as the model of the dragged item, as specified by the ng-repeat of the [`source`](#source) ui-sortable element and the item's [`index`](#index).
25+
26+
### moved
27+
Type: [Object](http://api.jquery.com/Types/#Object)/`undefined`
28+
Holds the model of the dragged item only when a sorting happens between two connected ui-sortable elements.
29+
In other words: `'moved' in ui.item.sortable` will return false only when a sorting is withing the same ui-sortable element ([`source`](#source) equals to the [`droptarget`](#droptarget)).
30+
31+
### received
32+
Type: [Boolean](http://api.jquery.com/Types/#Boolean)
33+
When sorting between two connected sortables, it will be set to true inside the `update` callback of the [`droptarget`](#droptarget).
34+
35+
### source
36+
Type: [jQuery](http://api.jquery.com/Types/#jQuery)
37+
Holds the ui-sortable element that the dragged item originated from.
38+
39+
### sourceModel
40+
Type: [Array](http://api.jquery.com/Types/#Array)
41+
Holds the array that is specified by the `ng-model` of the [`source`](#source) ui-sortable element.
42+
43+
44+
## Methods
45+
46+
### cancel[()](http://api.jquery.com/Types/#Function)
47+
Returns: Nothing
48+
Can be called inside the `update` callback, in order to prevent/revert a sorting.
49+
Should be used instead of the [jquery-ui-sortable cancel()](http://api.jqueryui.com/sortable/#method-cancel) method.
50+
51+
### isCanceled[()](http://api.jquery.com/Types/#Function)
52+
Returns: [Boolean](http://api.jquery.com/Types/#Boolean)
53+
Returns whether the current sorting is marked as canceled, by an earlier call to [`ui.item.sortable.cancel()`](#cancel).
54+
55+
### isCustomHelperUsed[()](http://api.jquery.com/Types/#Function)
56+
Returns: [Boolean](http://api.jquery.com/Types/#Boolean)
57+
Returns whether the [`helper`](http://api.jqueryui.com/sortable/#option-helper) element used for the current sorting, is one of the original ui-sortable list elements.

README.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ Apply the directive to your form elements:
4242
* `ui-sortable` element should only contain one `ng-repeat` and not any other elements (above or below).
4343
Otherwise the index matching of the generated DOM elements and the `ng-model`'s items will break.
4444
**In other words: The items of `ng-model` must match the indexes of the generated DOM elements.**
45-
* `ui-sortable` lists containing many 'types' of items can be implemented by using dynamic template loading [with ng-include](http://stackoverflow.com/questions/14607879/angularjs-load-dynamic-template-html-within-directive/14621927#14621927) or a [loader directive](https://gist.github.com/thgreasi/7152499c0e91973c4820), to determine how each model item should be rendered. Also take a look at the [Tree with dynamic template](http://codepen.io/thgreasi/pen/uyHFC) example.
45+
* `ui-sortable` lists containing many 'types' of items can be implemented by using dynamic template loading [with ng-include](http://stackoverflow.com/questions/14607879/angularjs-load-dynamic-template-html-within-directive/14621927#14621927) or a [loader directive](https://github.com/thgreasi/tg-dynamic-directive), to determine how each model item should be rendered. Also take a look at the [Tree with dynamic template](http://codepen.io/thgreasi/pen/uyHFC) example.
4646

4747
### Options
4848

49-
All the [jQueryUI Sortable options](http://api.jqueryui.com/sortable/) can be passed through the directive.
49+
All the [jQueryUI Sortable options](http://api.jqueryui.com/sortable/) can be passed through the directive.
50+
Additionally, the `ui` argument of the available callbacks gets enriched with some extra properties as specified to the [API.md file](API.md#uiitemsortable-api-documentation).
5051

5152

5253
```js
@@ -69,6 +70,41 @@ myAppModule.controller('MyController', function($scope) {
6970
When using event callbacks ([start](http://api.jqueryui.com/sortable/#event-start)/[update](http://api.jqueryui.com/sortable/#event-update)/[stop](http://api.jqueryui.com/sortable/#event-stop)...), avoid manipulating DOM elements (especially the one with the ng-repeat attached).
7071
The suggested pattern is to use callbacks for emmiting events and altering the scope (inside the 'Angular world').
7172

73+
#### Floating
74+
75+
To have a smooth horizontal-list reordering, jquery.ui.sortable needs to detect the orientation of the list.
76+
This detection takes place during the initialization of the plugin (and some of the checks include: whether the first item is floating left/right or if 'axis' parameter is 'x', etc).
77+
There is also a [known issue](bugs.jqueryui.com/ticket/7498) about initially empty horizontal lists.
78+
79+
To provide a solution/workaround (till jquery.ui.sortable.refresh() also tests the orientation or a more appropriate method is provided), ui-sortable directive provides a `ui-floating` option as an extra to the [jquery.ui.sortable options](http://api.jqueryui.com/sortable/).
80+
81+
```html
82+
<ul ui-sortable="{ 'ui-floating': true }" ng-model="items">
83+
<li ng-repeat="item in items">{{ item }}</li>
84+
</ul>
85+
```
86+
87+
**OR**
88+
89+
```js
90+
$scope.sortableOptions = {
91+
'ui-floating': true
92+
};
93+
```
94+
```html
95+
<ul ui-sortable="sortableOptions" ng-model="items">
96+
<li ng-repeat="item in items">{{ item }}</li>
97+
</ul>
98+
```
99+
100+
101+
**ui-floating** (default: undefined)
102+
Type: [Boolean](http://api.jquery.com/Types/#Boolean)/[String](http://api.jquery.com/Types/#String)/`undefined`
103+
* **undefined**: Relies on jquery.ui to detect the list's orientation.
104+
* **false**: Forces jquery.ui.sortable to detect the list as vertical.
105+
* **true**: Forces jquery.ui.sortable to detect the list as horizontal.
106+
* **"auto"**: Detects on each drag `start` if the element is floating or not.
107+
72108
#### Canceling
73109

74110
Inside the `update` callback, you can check the item that is dragged and cancel the sorting.
@@ -138,6 +174,7 @@ For more details about the events check the [jQueryUI API documentation](http://
138174
- [Filtering](http://codepen.io/thgreasi/pen/mzGbq) ([details](https://github.com/angular-ui/ui-sortable/issues/113))
139175
- [Ordering 1](http://codepen.io/thgreasi/pen/iKEHd) & [Ordering 2](http://plnkr.co/edit/XPUzJjdvwE0QWQ6py6mQ?p=preview) ([details](https://github.com/angular-ui/ui-sortable/issues/70))
140176
- [Cloning](http://codepen.io/thgreasi/pen/qmvhG) ([details](https://github.com/angular-ui/ui-sortable/issues/139))
177+
- [Horizontal List](http://codepen.io/thgreasi/pen/wsfjD)
141178
- [Tree with dynamic template](http://codepen.io/thgreasi/pen/uyHFC)
142179
- Canceling
143180
- [Connected Lists With Max Size](http://codepen.io/thgreasi/pen/IdvFc)

bower.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-ui-sortable",
3-
"version": "0.12.11",
3+
"version": "0.13.0",
44
"description": "This directive allows you to jQueryUI Sortable.",
55
"author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
66
"license": "MIT",
@@ -16,11 +16,11 @@
1616
"package.json"
1717
],
1818
"dependencies": {
19-
"angular": "~1.2.x",
19+
"angular": ">=1.2.x",
2020
"jquery-ui": ">=1.9"
2121
},
2222
"devDependencies": {
23-
"angular-mocks": "~1.2.x",
23+
"angular-mocks": ">=1.2.x",
2424
"jquery-simulate": "latest"
2525
}
2626
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-ui-sortable",
3-
"version": "0.12.11",
3+
"version": "0.13.0",
44
"description": "This directive allows you to jQueryUI Sortable.",
55
"author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
66
"license": "MIT",

src/sortable.js

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,22 @@ angular.module('ui.sortable', [])
2828
return helperOption === 'clone' || (typeof helperOption === 'function' && ui.item.sortable.isCustomHelperUsed());
2929
}
3030

31+
// thanks jquery-ui
32+
function isFloating (item) {
33+
return (/left|right/).test(item.css('float')) || (/inline|table-cell/).test(item.css('display'));
34+
}
35+
36+
function afterStop(e, ui) {
37+
ui.item.sortable._destroy();
38+
}
39+
3140
var opts = {};
3241

42+
// directive specific options
43+
var directiveOpts = {
44+
'ui-floating': undefined
45+
};
46+
3347
var callbacks = {
3448
receive: null,
3549
remove:null,
@@ -42,7 +56,7 @@ angular.module('ui.sortable', [])
4256
helper: null
4357
};
4458

45-
angular.extend(opts, uiSortableConfig, scope.$eval(attrs.uiSortable));
59+
angular.extend(opts, directiveOpts, uiSortableConfig, scope.$eval(attrs.uiSortable));
4660

4761
if (!angular.element.fn || !angular.element.fn.jquery) {
4862
$log.error('ui.sortable: jQuery should be included before AngularJS!');
@@ -65,9 +79,19 @@ angular.module('ui.sortable', [])
6579
});
6680

6781
callbacks.start = function(e, ui) {
82+
if (opts['ui-floating'] === 'auto') {
83+
// since the drag has started, the element will be
84+
// absolutely positioned, so we check its siblings
85+
var siblings = ui.item.siblings();
86+
angular.element(e.target).data('ui-sortable').floating = isFloating(siblings);
87+
}
88+
6889
// Save the starting position of dragged item
6990
ui.item.sortable = {
91+
model: ngModel.$modelValue[ui.item.index()],
7092
index: ui.item.index(),
93+
source: ui.item.parent(),
94+
sourceModel: ngModel.$modelValue,
7195
cancel: function () {
7296
ui.item.sortable._isCanceled = true;
7397
},
@@ -78,7 +102,12 @@ angular.module('ui.sortable', [])
78102
return !!ui.item.sortable._isCustomHelperUsed;
79103
},
80104
_isCanceled: false,
81-
_isCustomHelperUsed: ui.item.sortable._isCustomHelperUsed
105+
_isCustomHelperUsed: ui.item.sortable._isCustomHelperUsed,
106+
_destroy: function () {
107+
angular.forEach(ui.item.sortable, function(value, key) {
108+
ui.item.sortable[key] = undefined;
109+
});
110+
}
82111
};
83112
};
84113

@@ -119,7 +148,9 @@ angular.module('ui.sortable', [])
119148
// the value will be overwritten with the old value
120149
if(!ui.item.sortable.received) {
121150
ui.item.sortable.dropindex = ui.item.index();
122-
ui.item.sortable.droptarget = ui.item.parent();
151+
var droptarget = ui.item.parent();
152+
ui.item.sortable.droptarget = droptarget;
153+
ui.item.sortable.droptargetModel = droptarget.scope().$eval(droptarget.attr('ng-model'));
123154

124155
// Cancel the sort (let ng-repeat do the sort for us)
125156
// Don't cancel if this is the received list because it has
@@ -229,25 +260,42 @@ angular.module('ui.sortable', [])
229260
// is still bound to the directive's element
230261
if (!!element.data('ui-sortable')) {
231262
angular.forEach(newVal, function(value, key) {
232-
if(callbacks[key]) {
263+
// if it's a custom option of the directive,
264+
// handle it approprietly
265+
if (key in directiveOpts) {
266+
if (key === 'ui-floating' && (value === false || value === true)) {
267+
element.data('ui-sortable').floating = value;
268+
}
269+
270+
opts[key] = value;
271+
return;
272+
}
273+
274+
if (callbacks[key]) {
233275
if( key === 'stop' ){
234276
// call apply after stop
235277
value = combineCallbacks(
236278
value, function() { scope.$apply(); });
279+
280+
value = combineCallbacks(value, afterStop);
237281
}
238282
// wrap the callback
239283
value = combineCallbacks(callbacks[key], value);
240284
} else if (wrappers[key]) {
241285
value = wrappers[key](value);
242286
}
243287

288+
opts[key] = value;
244289
element.sortable('option', key, value);
245290
});
246291
}
247292
}, true);
248293

249294
angular.forEach(callbacks, function(value, key) {
250295
opts[key] = combineCallbacks(value, opts[key]);
296+
if( key === 'stop' ){
297+
opts[key] = combineCallbacks(opts[key], afterStop);
298+
}
251299
});
252300

253301
} else {

0 commit comments

Comments
 (0)