forked from bevacqua/angularjs-dragula
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.js
114 lines (110 loc) · 3.44 KB
/
service.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
102
103
104
105
106
107
108
109
110
111
112
113
114
'use strict';
var dragula = require('dragula');
var dragulaKey = '$$dragula';
var replicateEvents = require('./replicate-events');
function register (angular) {
return [function dragulaService () {
return {
add: add,
find: find,
options: setOptions,
destroy: destroy,
handleModels: handleModels
};
function handleModels(scope, drake){
if(drake.registered){ // do not register events twice
return;
}
var dragElm;
var dragIndex;
var dropIndex;
var sourceModel;
drake.on('remove',function removeModel (el, source) {
if (!drake.models) {
return;
}
sourceModel = drake.models[drake.containers.indexOf(source)];
scope.$applyAsync(function applyRemove() {
sourceModel.splice(dragIndex, 1);
drake.emit('remove-model', el, source);
});
});
drake.on('drag',function dragModel (el, source) {
dragElm = el;
dragIndex = domIndexOf(el, source);
});
drake.on('drop',function dropModel (dropElm, target, source) {
if (!drake.models) {
return;
}
dropIndex = domIndexOf(dropElm, target);
scope.$applyAsync(function applyDrop() {
sourceModel = drake.models[drake.containers.indexOf(source)];
if (target === source) {
sourceModel.splice(dropIndex, 0, sourceModel.splice(dragIndex, 1)[0]);
} else {
var notCopy = dragElm === dropElm;
var targetModel = drake.models[drake.containers.indexOf(target)];
var dropElmModel = notCopy ? sourceModel[dragIndex] : angular.copy(sourceModel[dragIndex]);
if (notCopy) {
sourceModel.splice(dragIndex, 1);
}
targetModel.splice(dropIndex, 0, dropElmModel);
target.removeChild(dropElm); // element must be removed for ngRepeat to apply correctly
}
drake.emit('drop-model', dropElm, target, source);
});
});
drake.registered = true;
}
function getOrCreateCtx (scope) {
var ctx = scope[dragulaKey];
if (!ctx) {
ctx = scope[dragulaKey] = {
bags: []
};
}
return ctx;
}
function domIndexOf(child, parent) {
return Array.prototype.indexOf.call(angular.element(parent).children(), child);
}
function add (scope, name, drake) {
var bag = find(scope, name);
if (bag) {
throw new Error('Bag named: "' + name + '" already exists in same angular scope.');
}
var ctx = getOrCreateCtx(scope);
bag = {
name: name,
drake: drake
};
ctx.bags.push(bag);
replicateEvents(angular, bag, scope);
if(drake.models){ // models to sync with (must have same structure as containers)
handleModels(scope, drake);
}
return bag;
}
function find (scope, name) {
var bags = getOrCreateCtx(scope).bags;
for (var i = 0; i < bags.length; i++) {
if (bags[i].name === name) {
return bags[i];
}
}
}
function destroy (scope, name) {
var bags = getOrCreateCtx(scope).bags;
var bag = find(scope, name);
var i = bags.indexOf(bag);
bags.splice(i, 1);
bag.drake.destroy();
}
function setOptions (scope, name, options) {
var bag = add(scope, name, dragula(options));
handleModels(scope, bag.drake);
}
}];
}
module.exports = register;