AngularJS - Using shared object to communicate between controllers & directives
by vacationlabs
HTML
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<div ng-app="MyModule" ng-controller="MyController">
<p>Pick a color: <select ng-options="color for color in ['red', 'blue', 'yellow']" ng-model="box1.color"></select></p>
<p>My coordinates are: top={{ box1.top }} & left={{ box1.left }}</p>
<div draggable="" options="box1"></div>
<hr />
<p>Pick a color: <select ng-options="color for color in ['red', 'blue', 'yellow']" ng-model="box2.color"></select></p>
<p>My coordinates are: top={{ box2.top }} & left={{ box2.left }}</p>
<div draggable="" options="box2"></div>
</div>
CSS
.draggable {
width: 100px;
height: 100px;
position: relative;
}
.draggable h3 {
position: absolute;
left: 20px;
top: 15px;
}
}
JavaScript
$('#draggable').draggable();
var mod = angular.module('MyModule', []);
mod.controller('MyController', ['$scope', function($scope) {
var can_drop = function(top, left, i) {
if(i==1) {
return !is_overlapping(top, left, $scope.box2.top, $scope.box2.left);
} else {
return !is_overlapping(top, left, $scope.box1.top, $scope.box1.left);
}
}
var is_overlapping = function(t1, l1, t2, l2) {
return Math.abs(t1-t2)<=100 && Math.abs(l1-l2)<=100;
}
$scope.box1 = {
'color' : 'red',
'can_drop' : can_drop,
'top' : null,
'left' : null,
'i' : 1
};
$scope.box2 = {
'color' : 'blue',
'can_drop' : can_drop,
'top' : null,
'left' : null,
'i' : 2
};
}]);
mod.directive('draggable', function() {
return {
'restrict' : 'A',
'scope' : {
'options' : '='
},
'template' : '<div class="draggable"><h3>Drag me around</h3></div>',
'replace' : true,
'link' : function(scope, element, attrs) {
var can_drop_fn = attrs.canDrop;
element.draggable();
scope.options.top = element.position().top;
scope.options.left = element.position().left;
scope.$watch('options.color', function(color) {
element.css('background', color);
});
element.bind('dragstop', function(evt, ui) {
if(scope.options.can_drop(ui.offset.top, ui.offset.left, scope.options.i)) {
scope.$apply(function() {
scope.options.top = ui.offset.top;
scope.options.left = ui.offset.left;
});
} else {
element.css({
'top' : scope.options.top,
'left' : scope.options.left
});
}
...