-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdraggable-list.js
101 lines (80 loc) · 2.82 KB
/
draggable-list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// angular-draggable-list
// ----------------------
// Copyright © 2014 Michael Murray | MIT license | https://github.com/nverba/angular-draggable-list
angular.module('draggableList', [])
.directive('draggableList', function () {
'use strict';
var isTouchDevice = !!('ontouchstart' in window),
dragData = {};
function isDropTarget(element) {
return element.parentElement === dragData.elem.parentElement;
}
function isNewTarget(scope) {
return dragData.from_index !== scope.$parent.$index;
}
function isTouchTarget(element) {
return element !== dragData.elem;
}
function update(scope, newIndex) {
scope.$apply(function () {
scope.draggableList.splice(newIndex, 0, scope.draggableList.splice(dragData.from_index, 1)[0]);
dragData.from_index = newIndex;
});
}
function getElement(e) {
return document.elementFromPoint(
e.changedTouches[0].clientX,
e.changedTouches[0].clientY
);
}
return {
restrict: 'A',
scope: {
draggableList: '=',
},
link: function (scope, elem, attrs) {
elem.bind('dragstart', function (e) {
// Firefox needs this to enable HTML5 draggable feature. (Set to 'Text' for IE compatability)
e.dataTransfer.setData('Text', 'Firefox wont drag without this???');
dragData.from_index = scope.$parent.$index;
dragData.elem = e.target || e.srcElement;
});
elem.bind('dragenter', function (e) {
if (isDropTarget(e.target || e.srcElement) && isNewTarget(scope)) { update(scope, scope.$parent.$index); }
});
elem.bind('dragover', function (e) {
e.preventDefault();
});
elem.bind('dragleave', function (e) {
// place holder
});
elem.bind('drop', function (e) {
e.preventDefault(); // important! stop firefox redirecting
});
elem.bind('dragend', function (e) {
dragData = {};
});
if (isTouchDevice) {
elem.bind('touchstart', function (e) {
dragData.from_index = scope.$parent.$index;
dragData.elem = e.target || e.srcElement;
});
elem.bind('touchmove', function (e) {
e.preventDefault();
var element = getElement(e),
newIndex;
if (isTouchTarget(element) && isDropTarget(element)) {
newIndex = Array.prototype.indexOf.call(element.parentElement.children, element);
update(scope, newIndex);
dragData.elem = element;
}
elem.addClass('touch-active');
});
elem.bind('touchend', function (e) {
dragData = {};
elem.removeClass('touch-active');
});
}
}
};
});