AngularJS cnSortable
Simple wrapper of jQuery UI sortable for AngularJS.
by chucknelson
HTML
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl">
<h1>Items</h1>
<ul cn-sortable on-sort="orderItems(itemUpdates)">
<li ng-repeat="item in items">
<input type="hidden" name="id" value="{{item.id}}" />
{{item.name}} | <a href="#" ng-click="deleteItem($index)">(delete)</a>
</li>
</ul>
<ul>
<li>
<form name="theForm" ng-submit="formSubmit()">
<label for="myName">New Item:</label>
<input name="myName" type="text" ng-model="newName" required />
<input name="submit" type="submit" value="Add Item" />
</form>
</li>
</ul>
<button name="reset" ng-click="reset()">Reset</button>
<div class="debugText">
Debug text in scope:<br />
{{debugText}}
</div>
<div class="debugText">
Last itemUpdates():<br />
{{itemUpdatesText}}
</div>
<p class="footerText">AngularJS {{angularVersionText}}</p>
</div>
CSS
.debugText {
margin: 10px 0;
padding: 5px;
background-color: #eee;
border: 1px solid #ccc;
}
.footerText {
font-size: .8em;
color: #888;
}
input.ng-dirty.ng-invalid {
border: 2px solid red;
}
JavaScript
'use strict';
var app = angular.module('angularTest', []);
app.controller('MainCtrl', ['$scope', 'filterFilter', 'orderByFilter', function($scope, filterFilter, orderByFilter) {
var nextId;
$scope.angularVersionText = angular.version.full + ', "' + angular.version.codeName + '"';
$scope.initItems = function() {
$scope.items = [
{id: 1, name: 'Item 1', sort_order: 0},
{id: 2, name: 'Item 2', sort_order: 1},
{id: 3, name: 'Item 3', sort_order: 2}
];
nextId = $scope.items.length + 1;
};
$scope.reset = function() {
$scope.initItems();
$scope.itemUpdatesText = '';
};
$scope.formSubmit = function() {
var newItem = {id: nextId, name: $scope.newName, sort_order: $scope.items.length};
$scope.items.push(newItem);
nextId++;
$scope.newName = '';
$scope.theForm.$setPristine();
};
//method in controller that takes itemUpdates from cnSortable and does something with them
//in this specific case we're using them to update each item in our model and then we sort the model by sort_order
$scope.orderItems = function(itemUpdates) {
itemUpdates.forEach(function(i) {
$scope.orderItem(i);
});
$scope.items = orderByFilter($scope.items, 'sort_order');
//debug
$scope.itemUpdatesText = orderByFilter(itemUpdates, 'newSortOrder');
};
$scope.orderItem = function(itemUpdate) {
var itemToOrder = filterFilter($scope.items, {id: itemUpdate.id}).pop();
itemToOrder.sort_order = itemUpdate.newSortOrder;
};
$scope.deleteItem = function(index) {
$scope.items.splice(index, 1);
};
//debug text
$scope.$watch('items', function() {
$scope.debugText = $scope.items;
});
//initial controller init
$scope.reset();
}]);
//somewhat generic sorting...