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

Merge branch 'v0.16.x-dev' #496

Merged
merged 13 commits into from
Dec 4, 2016
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
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: node_js
node_js:
- '0.10'
addons:
firefox: "latest"
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ update: function(event, ui) {

**Single sortable** [demo](http://codepen.io/thgreasi/pen/QKmWGj)
```
create

/* dragging starts */
helper
start
activate

Expand All @@ -174,6 +178,11 @@ stop
**Connected sortables** [demo](http://codepen.io/thgreasi/pen/YGazpJ)

```
list A: create
list B: create

/* dragging starts from sortable A to B */
list A: helper
list A: start
list B: activate
list A: activate
Expand All @@ -199,6 +208,30 @@ list A: stop

For more details about the events check the [jQueryUI API documentation](http://api.jqueryui.com/sortable/).

## Integrating with directives doing transclusion
Wrap the transclusion directive element with the ui-sortable directive and set the `items` to target your `ng-repeat`ed elements. Following best practices, it is also highly recommended that you add a `track by` expression to your `ng-repeat`. [Angular Meterial example](http://codepen.io/thgreasi/pen/NbyLVK).

```js
myAppModule.controller('MyController', function($scope) {
$scope.items = ["One", "Two", "Three"];

$scope.sortableOptions = {
items: '.sortable-item'
// It is suggested to use the most specific cssselector you can,
// after analyzing the DOM elements generated by the transclusion directive
// eg: items: '> .transclusionLvl1 > .transclusionLvl2 > .sortable-item'
};
});
```

```html
<div ui-sortable="sortableOptions" ng-model="items">
<a-transclusion-directive>
<div ng-repeat="item in items" class="sortable-item">{{ item }}</div>
</a-transclusion-directive>
</div>
```

## Examples

- [Simple Demo](http://codepen.io/thgreasi/pen/wzmvgw)
Expand All @@ -224,6 +257,7 @@ For more details about the events check the [jQueryUI API documentation](http://
## Integrations
- [firebase](http://codepen.io/thgreasi/pen/repEZg?editors=0010)
- [ui.bootstrap.accordion](http://plnkr.co/edit/TGIeeEbbvJwpJ3WRqo2z?p=preview)
- [Angular Meterial](http://codepen.io/thgreasi/pen/NbyLVK) (thanks yenoh2)
- [Asynchronous loading jQuery+jQueryUI with crisbeto/angular-ui-sortable-loader](https://github.com/crisbeto/angular-ui-sortable-loader)

## Reporting Issues
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-ui-sortable",
"version": "0.15.1",
"version": "0.16.0",
"description": "This directive allows you to jQueryUI Sortable.",
"author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-ui-sortable",
"version": "0.15.1",
"version": "0.16.0",
"description": "This directive allows you to jQueryUI Sortable.",
"author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
"license": "MIT",
Expand Down
65 changes: 37 additions & 28 deletions src/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ angular.module('ui.sortable', [])
}
return;
}

if (!defaultOptions) {
defaultOptions = angular.element.ui.sortable().options;
}
Expand Down Expand Up @@ -186,16 +186,13 @@ 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;
function getElementContext(elementScopes, element) {
for (var i = 0; i < elementScopes.length; i++) {
var x = elementScopes[i];
if (x.element[0] === element[0]) {
result = x.scope;
break;
var c = elementScopes[i];
if (c.element[0] === element[0]) {
return c;
}
}
return result;
}

function afterStop(e, ui) {
Expand Down Expand Up @@ -266,7 +263,8 @@ angular.module('ui.sortable', [])
ui.item.sortable = {
model: ngModel.$modelValue[index],
index: index,
source: ui.item.parent(),
source: element,
sourceList: ui.item.parent(),
sourceModel: ngModel.$modelValue,
cancel: function () {
ui.item.sortable._isCanceled = true;
Expand All @@ -283,16 +281,33 @@ angular.module('ui.sortable', [])
angular.forEach(ui.item.sortable, function(value, key) {
ui.item.sortable[key] = undefined;
});
},
_connectedSortables: [],
_getElementContext: function (element) {
return getElementContext(this._connectedSortables, element);
}
};
};

callbacks.activate = function(e, ui) {
var isSourceContext = ui.item.sortable.source === element;
var savedNodesOrigin = isSourceContext ?
ui.item.sortable.sourceList :
element;
var elementContext = {
element: element,
scope: scope,
isSourceContext: isSourceContext,
savedNodesOrigin: savedNodesOrigin
};
// save the directive's scope so that it is accessible from ui.item.sortable
ui.item.sortable._connectedSortables.push(elementContext);

// 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
// both lists when dragging between connected lists.
savedNodes = element.contents();
savedNodes = savedNodesOrigin.contents();

// If this list has a placeholder (the connected lists won't),
// don't inlcude it in saved nodes.
Expand All @@ -301,16 +316,6 @@ angular.module('ui.sortable', [])
var excludes = getPlaceholderExcludesludes(element, placeholder);
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 @@ -319,11 +324,12 @@ angular.module('ui.sortable', [])
// the value will be overwritten with the old value
if(!ui.item.sortable.received) {
ui.item.sortable.dropindex = getItemIndex(ui.item);
var droptarget = ui.item.parent();
var droptarget = ui.item.closest('[ui-sortable]');
ui.item.sortable.droptarget = droptarget;
ui.item.sortable.droptargetList = ui.item.parent();

var droptargetScope = getElementScope(ui.item.sortable._connectedSortables, droptarget);
ui.item.sortable.droptargetModel = droptargetScope.ngModel;
var droptargetContext = ui.item.sortable._getElementContext(droptarget);
ui.item.sortable.droptargetModel = droptargetContext.scope.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 All @@ -343,7 +349,8 @@ angular.module('ui.sortable', [])
// That way it will be garbage collected.
savedNodes = savedNodes.not(sortingHelper);
}
savedNodes.appendTo(element);
var elementContext = ui.item.sortable._getElementContext(element);
savedNodes.appendTo(elementContext.savedNodesOrigin);

// If this is the target connected list then
// it's safe to clear the restored nodes since:
Expand Down Expand Up @@ -392,7 +399,8 @@ angular.module('ui.sortable', [])
// That way it will be garbage collected.
savedNodes = savedNodes.not(sortingHelper);
}
savedNodes.appendTo(element);
var elementContext = ui.item.sortable._getElementContext(element);
savedNodes.appendTo(elementContext.savedNodesOrigin);
}

// It's now safe to clear the savedNodes
Expand Down Expand Up @@ -433,7 +441,8 @@ angular.module('ui.sortable', [])
item.sortable = {
model: ngModel.$modelValue[index],
index: index,
source: item.parent(),
source: element,
sourceList: item.parent(),
sourceModel: ngModel.$modelValue,
_restore: function () {
angular.forEach(item.sortable, function(value, key) {
Expand All @@ -459,7 +468,7 @@ angular.module('ui.sortable', [])
var sortableWidgetInstance = getSortableWidgetInstance(element);
if (!!sortableWidgetInstance) {
var optsDiff = patchUISortableOptions(newVal, oldVal, sortableWidgetInstance);

if (optsDiff) {
element.sortable('option', optsDiff);
}
Expand All @@ -475,7 +484,7 @@ angular.module('ui.sortable', [])
} else {
$log.info('ui.sortable: ngModel not provided!', element);
}

// Create sortable
element.sortable(opts);
}
Expand Down
Loading