<!DOCTYPE html>
<html ng-app="listApp">
<head>
<meta charset="UTF-8">
<title>Simple Angular Draggable List</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="script.js"></script>
</head>
<body ng-controller="listCtrl">
<ul class="list-group" ng-init="initList()">
<li class="list-group-item" id="item-{{item.Id}}" ng-repeat="item in listItems track by $index" ml-draggable-list="listItems">{{item.Name}}</li>
</ul>
</div>
</body>
</html>
var app = angular.module("listApp", []);
app.controller("listCtrl", function($scope) {
// Example list for ng-repeat
$scope.listItems = [];
$scope.initList = function()
{
$scope.listItems.push({Id:0, Name:'one'});
$scope.listItems.push({Id:1, Name:'two'});
$scope.listItems.push({Id:2, Name:'three'});
}
});
// Simple and reusable directive for making list elements draggable.
app.directive('mlDraggableList', function(){
return {
restrict: 'A', //attribute only
link: function(scope, elem, attr, ctrl) {
//Drag functions
scope.swapItems = function(sourceElemId, targetElemId, collectionName)
{
var source = scope[collectionName][sourceElemId];
scope[collectionName][sourceElemId] = scope[collectionName][targetElemId];
scope[collectionName][targetElemId] = source;
scope.$apply();
}
scope.listDragStart = function()
{
var sourceElem = event.target.id;
var startElemId = $(event.target).attr("dlid");
event.dataTransfer.setData("dlid", startElemId);
}
scope.listDragOver = function () {
event.preventDefault();
}
scope.listDrop = function (collectionName) {
event.preventDefault();
var targetElem = $(event.target).closest('li')
var targetElemId = targetElem.attr("dlid");
var sourceElemId = event.dataTransfer.getData("dlid");
if (sourceElemId != targetElemId)
{
scope.swapItems(sourceElemId, targetElemId, collectionName);
}
}
// Wire elements on last ng-repeat
if (scope.$last){
scope.dllistItems = scope.$eval("scope." + attr.mlDraggableList);
$("li[ml-draggable-list]").each(function(index, item){
$(item).attr("dlid", index); // Id used for swapping elements
$(item).attr("draggable", true);
$(item).bind('dragstart', function(e) { // Capture source element
scope.$eval("listDragStart()");
});
$(item).bind('dragover', function(e) { // overriding default behavior
scope.$eval("listDragOver()");
});
$(item).bind('drop', function(e) {
scope.$eval("listDrop('" + attr.mlDraggableList + "')"); // When element is dropped
});
});
}
}
};
});
/* Styles go here */
## Synopsis
Simple and reusable directive for making list elements draggable.
## Code Example
To make elements draggable add "ml-draggable-list" custom attribute and pass in the collection name.
```
<ul class="list-group" ng-init="initList()">
<li class="list-group-item" id="item-{{item.Id}}" ng-repeat="item in listItems track by $index" ml-draggable-list="listItems">{{item.Name}}</li>
</ul>
```
## Motivation
Needed a simple and reusable directive to make elements in ng-repeat draggable.
## Installation
```
Step 1 - Add directive e.g. [yourApp].directive('mlDraggableList', function(){
Step 2 - Add "ml-draggable-list" attribute to your ng-repeat and pass in the collection name e.g. ="ml-draggable-list='listItems'"
```
## Contributors
tarikub
## License
MIT: http://opensource.org/licenses/MIT