How to Create simple drag and Drop in angularjs
Solution 1
I just posted this to my brand spanking new blog: http://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop/
Code here: https://github.com/logicbomb/lvlDragDrop
Demo here: http://logicbomb.github.io/ng-directives/drag-drop.html
Here are the directives these rely on a UUID service which I've included below:
var module = angular.module("lvl.directives.dragdrop", ['lvl.services']);
module.directive('lvlDraggable', ['$rootScope', 'uuid', function($rootScope, uuid) {
return {
restrict: 'A',
link: function(scope, el, attrs, controller) {
console.log("linking draggable element");
angular.element(el).attr("draggable", "true");
var id = attrs.id;
if (!attrs.id) {
id = uuid.new()
angular.element(el).attr("id", id);
}
el.bind("dragstart", function(e) {
e.dataTransfer.setData('text', id);
$rootScope.$emit("LVL-DRAG-START");
});
el.bind("dragend", function(e) {
$rootScope.$emit("LVL-DRAG-END");
});
}
}
}]);
module.directive('lvlDropTarget', ['$rootScope', 'uuid', function($rootScope, uuid) {
return {
restrict: 'A',
scope: {
onDrop: '&'
},
link: function(scope, el, attrs, controller) {
var id = attrs.id;
if (!attrs.id) {
id = uuid.new()
angular.element(el).attr("id", id);
}
el.bind("dragover", function(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
return false;
});
el.bind("dragenter", function(e) {
// this / e.target is the current hover target.
angular.element(e.target).addClass('lvl-over');
});
el.bind("dragleave", function(e) {
angular.element(e.target).removeClass('lvl-over'); // this / e.target is previous target element.
});
el.bind("drop", function(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
if (e.stopPropagation) {
e.stopPropagation(); // Necessary. Allows us to drop.
}
var data = e.dataTransfer.getData("text");
var dest = document.getElementById(id);
var src = document.getElementById(data);
scope.onDrop({dragEl: src, dropEl: dest});
});
$rootScope.$on("LVL-DRAG-START", function() {
var el = document.getElementById(id);
angular.element(el).addClass("lvl-target");
});
$rootScope.$on("LVL-DRAG-END", function() {
var el = document.getElementById(id);
angular.element(el).removeClass("lvl-target");
angular.element(el).removeClass("lvl-over");
});
}
}
}]);
UUID service
angular
.module('lvl.services',[])
.factory('uuid', function() {
var svc = {
new: function() {
function _p8(s) {
var p = (Math.random().toString(16)+"000000000").substr(2,8);
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
}
return _p8() + _p8(true) + _p8(true) + _p8();
},
empty: function() {
return '00000000-0000-0000-0000-000000000000';
}
};
return svc;
});
Solution 2
Angular doesn't provide snazzy UI elements like drag and drop. That's not really Angular's purpose. However, there are a few well known directives that provide drag and drop. Here are two that I've used.
https://github.com/angular-ui/ui-sortable
https://github.com/codef0rmer/angular-dragdrop
Solution 3
I'm a bit late to the party, but I have my own directive that looks like it'll fit your case (You can adapt it yourself). It's a modification of the ng-repeat directive that's specifically built for list re-ordering via DnD. I built it as I don't like JQuery UI (preference for less libraries than anything else) also I wanted mine to work on touch screens too ;).
Code is here: http://codepen.io/SimeonC/pen/AJIyC
Blog post is here: http://sdevgame.wordpress.com/2013/08/27/angularjs-drag-n-drop-re-order-in-ngrepeat/
Solution 4
Modified from the angular-drag-and-drop-lists examples page
Markup
<div class="row">
<div ng-repeat="(listName, list) in models.lists" class="col-md-6">
<ul dnd-list="list">
<li ng-repeat="item in list"
dnd-draggable="item"
dnd-moved="list.splice($index, 1)"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
ng-class="{'selected': models.selected === item}"
draggable="true">{{item.label}}</li>
</ul>
</div>
</div>
Angular
var app = angular.module('angular-starter', [
'ui.router',
'dndLists'
]);
app.controller('MainCtrl', function($scope){
$scope.models = {
selected: null,
lists: {"A": [], "B": []}
};
// Generate initial model
for (var i = 1; i <= 3; ++i) {
$scope.models.lists.A.push({label: "Item A" + i});
$scope.models.lists.B.push({label: "Item B" + i});
}
// Model to JSON for demo purpose
$scope.$watch('models', function(model) {
$scope.modelAsJson = angular.toJson(model, true);
}, true);
});
Library can be installed via bower or npm: angular-drag-and-drop-lists
Solution 5
adapt-strap has very light weight module for this. here is the fiddle. Here are some attributes that are supported. There are more.
ad-drag="true"
ad-drag-data="car"
ad-drag-begin="onDragStart($data, $dragElement, $event);"
ad-drag-end="onDataEnd($data, $dragElement, $event);"
Priya Bose
Updated on July 14, 2022Comments
-
Priya Bose almost 2 years
I want to know how to do drag and drop by using AngularJs.
This is what I have so far:
<span><input type="checkbox" ng-model="master"><span>SelectAll</span></span> <div ng-repeat="todo in todos"> <div ng-hide="enableEditor"> <a href="#">Drag</a> <input id="checkSlave" type="checkbox" ng-checked="master" ng-model="todo.done"> <span ng-if="checked" ng-show="removed" ng-bind="todo.task_name" class="removed"></span> <span ng-bind="todo.task_name"></span> <span ng-bind="todo.state"></span> <a href="#" ng-click="editTask(todo.task_id,todo.task_name,editMode=!editMode)">Edit</a> </div> </div> <div ng-show="enableEditor"> <input type="text" ng-show="editMode" ng-model="todo.task_name" ng-change="update(todo.task_id,todo.task_name)"> <a href="#" ng-click="saveTask(todo.task_id,todo.task_name,editMode=!editMode)">Save</a> <a href="#" ng-click="cancelTask(todo.task_id,todo.task_name,editMode=!editMode)">Cancel</a> </div> </div>
-
jcollum over 10 yearsI'm getting an error with this code in Angular 1.2.6. "Multiple directives [lvlDropTarget, tooltip] asking for new/isolated scope on: <div ...". Looks like a collision with bootstrap tooltips.
-
Andrew Magee about 10 yearsI think
stopPropogation
here should bestopPropagation
. Can't do the edit myself as it's less than 6 characters :/ -
DusanV about 10 years@AndrewMagee It has been updated in github - github.com/logicbomb/lvlDragDrop
-
CodyBugstein over 9 yearsWhy do your attribute names start with
x-
when the directive names don't? -
DusanV over 9 yearsPrefixing a nonstandard attribute with
x-
allows the HTML to pass valuation. It's not necessary, and I probably shouldn't have added them. -
dwp4ge almost 9 yearsIf including jQuery and your getting an "Cannot call method 'setData' of undefined" error. Use
e.originalEvent.dataTransfer
instead ofe.dataTransfer
-
caub over 8 yearswhich would you advise?
-
Wasimakram Mulla about 8 yearsThis is awesome. It has all the features in it
-
jrran90 about 8 yearsthank you for this, it's not clear on the documentation :) this is much more easy :)
-
Daniel Viglione almost 8 yearsI haven't tried it yet but the grid looks promising
-
MMR over 7 yearsHow to include it in my project once after installing it through npm
-
Devner over 7 years@MMR You can do it in the following way:
angular.module("demo", ["dndLists"]);
Replace "demo" with your app name. Addangular-drag-and-drop-lists.min.js
to the script tag in your HTML file. That should do it. -
tic over 7 years
$rootScope.$on
Gross -
Dennis Xavier over 4 years'ondrop' function doesn't trigger for me.