gm.drag-drop
Advanced tools
Comparing version 0.1.0 to 0.1.4
@@ -8,3 +8,4 @@ (function() { | ||
.module('gm.dragDrop', []) | ||
.directive('gmDraggable', ['$document', gmDraggable]) | ||
.directive('gmDraggable', ['$window', '$document', gmDraggable]) | ||
.directive('gmOnHover', gmOnHover) | ||
.directive('gmOnDrop', gmOnDrop); | ||
@@ -14,5 +15,11 @@ | ||
function gmDraggable($document) { | ||
return function(scope, element, attr) { | ||
function apply(scope, attr, event) { | ||
scope.$apply(function() { | ||
scope.$eval(attr)(dragOb, event); | ||
}); | ||
} | ||
function gmDraggable($window, $document) { | ||
return function(scope, element, attrs) { | ||
var startX = 0, | ||
@@ -23,34 +30,40 @@ startY = 0, | ||
element.css({ | ||
cursor: 'pointer' | ||
}); | ||
element.on('mousedown', function(event) { | ||
var cancelWatch = null; | ||
// Handle will become a regular element, so if anything is returned, | ||
// we need to wrap that in angular.element(...) to bind events to it | ||
var handle = element[0].querySelectorAll('gm-drag-handle, [gm-drag-handle], .gm-drag-handle'); | ||
(handle.length ? angular.element(handle) : element).on('mousedown', function(event) { | ||
// Prevent default dragging of selected content | ||
event.preventDefault(); | ||
dragOb = scope.$eval(attr.gmDraggable); | ||
dragOb.$$gmDropZone = attr.gmDropZone; | ||
cancelWatch = scope.$watch(function() { | ||
return element.prop('innerHTML'); | ||
}, function(val) { | ||
if(clone) | ||
clone.prop('innerHTML', val); | ||
}); | ||
dragOb = scope.$eval(attrs.gmDraggable); | ||
dragOb.$$gmDropZone = attrs.gmDropZone; | ||
clone = element.clone(); | ||
element.addClass('gm-drag-element').after(clone); | ||
clone.css({ | ||
visibility: 'hidden', | ||
}); | ||
element.after(clone); | ||
element.css({ | ||
position: 'relative', | ||
pointerEvents: 'none' | ||
}); | ||
element.addClass('gm-dragging'); | ||
}).addClass('gm-dragging'); | ||
var elBoundingRect = element[0].getBoundingClientRect(); | ||
absParent.css({ | ||
position: 'absolute', | ||
zIndex: '2000', | ||
top: elBoundingRect.top + 'px', | ||
left: elBoundingRect.left + 'px' | ||
top: elBoundingRect.top + $window.scrollY + 'px', | ||
left: elBoundingRect.left + 'px', | ||
width: elBoundingRect.width + 'px' | ||
}); | ||
$document.find('body').append(absParent); | ||
absParent.append(element); | ||
absParent.append(clone); | ||
@@ -64,3 +77,3 @@ startX = event.pageX; | ||
function mousemove(event) { | ||
element.css({ | ||
clone.css({ | ||
top: event.pageY - startY + 'px', | ||
@@ -71,17 +84,15 @@ left: event.pageX - startX + 'px' | ||
function mouseup() { | ||
if(dragOb) { | ||
dragOb = null; | ||
clone.replaceWith(element); | ||
} else { | ||
clone.remove(); | ||
function mouseup() { | ||
if(dragOb) { | ||
if(attrs.gmOnInvalidDrop) { | ||
apply(scope, attrs.gmOnInvalidDrop); | ||
} | ||
dragOb = null; | ||
} | ||
element.css({ | ||
position: '', | ||
top: '', | ||
left: '', | ||
pointerEvents: '' | ||
}); | ||
element.removeClass('gm-dragging'); | ||
cancelWatch(); | ||
element.removeClass('gm-drag-element'); | ||
clone.remove(); | ||
absParent.remove(); | ||
@@ -94,2 +105,16 @@ $document.off('mousemove', mousemove); | ||
function gmOnHover() { | ||
return function(scope, element, attr) { | ||
element.on('mouseover', function(e) { | ||
if(!dragOb) | ||
return; | ||
if(dragOb.$$gmDropZone == attr.gmDropZone) { | ||
apply(scope, attr.gmOnHover, e); | ||
} | ||
}); | ||
} | ||
} | ||
function gmOnDrop() { | ||
@@ -100,3 +125,3 @@ return function(scope, element, attr) { | ||
return; | ||
if(dragOb.$$gmDropZone == attr.gmDropZone) { | ||
@@ -119,7 +144,4 @@ element.addClass('gm-dropping'); | ||
if(dragOb.$$gmDropZone == attr.gmDropZone) { | ||
scope.$apply(function() { | ||
if(scope.$eval(attr.gmOnDrop)(dragOb)) { | ||
dragOb = null; | ||
} | ||
}); | ||
apply(scope, attr.gmOnDrop); | ||
dragOb = null; | ||
} | ||
@@ -126,0 +148,0 @@ |
{ | ||
"name": "gm.drag-drop", | ||
"version": "0.1.0", | ||
"version": "0.1.4", | ||
"description": "Angular module to add simple, data-driven drag and drop functionality", | ||
@@ -13,3 +13,8 @@ "main": "gm.dragDrop.js", | ||
}, | ||
"author": "", | ||
"author": "Greg McGee <spongessuck@gmail.com>", | ||
"keywords": [ | ||
"angularjs", | ||
"drag", | ||
"drop" | ||
], | ||
"license": "MIT", | ||
@@ -16,0 +21,0 @@ "bugs": { |
# gm.dragDrop | ||
Angular directive to add simple, data-driven drag-drop functionality | ||
Angular directives to add native, simple, data-driven drag and drop functionality. | ||
## Include | ||
gm.dragDrop is available on both NPM and Bower: | ||
$ npm/bower install gm.drag-drop --save | ||
## Use | ||
First, add the `gm.dragDrop` module to your app's dependencies: | ||
```javascript | ||
var app = angular.module('myApp', ['gm.dragDrop']); | ||
``` | ||
There are 3 directives included in the module: `gmDraggable`, `gmOnDrop`, and `gmOnHover`. Adding the `gmDraggable` directive to an element makes it draggable. Adding the `gmOnDrop` directive to an element sets it as a drop zone for the draggable element. Set the value of `gmOnHover` or `gmOnDrop` to a function that will be called when the dragged element is over or released on an element, respectively. Set the value of `gmDraggable` to the object you want to be passed to `gmOnDrop`. | ||
Items with `gmDraggable` set can also assign a function to a `gmOnInvalidDrop` attribute, which will be called if the item is dropped anywhere but a valid drop zone. | ||
#### Sample controller: | ||
```javascript | ||
... | ||
this.data = { key: "number", value: "1" } | ||
this.onHover = function(_data, mouseEvent) { | ||
console.log('hovering', _data.key, _data.value); // hovering number 1 | ||
} | ||
this.onDrop = function(_data) { | ||
console.log('dropped', _data.key, _data.value); // dropped number 1 | ||
} | ||
this.invalidDrop = function(_data) { | ||
console.log('invalid drop', _data.key, _data.value); // invalid drop number 1 | ||
} | ||
... | ||
``` | ||
#### Sample template: | ||
```html | ||
<span gm-draggable="$ctrl.data" gm-on-invalid-drop='$ctrl.invalidDrop'>Number {{data.value}}</span> | ||
<div style='width:30%; float:right; padding:50px; border:solid black 1px' gm-on-drop="$ctrl.onDrop" gm-on-hover='$ctrl.onHover'>Drop Area</div> | ||
``` | ||
#### Style | ||
You can define style for three classes, `.gm-drag-element`, `.gm-dragging` and `.gm-dropping`, to set the style of the original element that was clicked, the element being dragged, and the drop zone element when the mouse hovers over it while dragging, respectively. | ||
## Drop Zones | ||
You can also define a `gm-drop-zone` attribute on both draggable elements and drop zones to control where elements can be dropped. Functions assigned to an element's `gm-on-drop` or `gm-on-hover` attributes will only be called when its `gm-drop-zone` attribute matches the dragged element's `gm-drop-zone` attribute. | ||
#### Sample template using drop zones: | ||
```html | ||
<span gm-draggable="$ctrl.data" gm-drop-zone='1'>Number {{data.value}}</span> | ||
<div style='width:30%; float:right; padding:50px; border:solid black 1px' gm-on-drop="$ctrl.onDrop" gm-drop-zone='2'>Cannot Drop Here</div> | ||
<div style='width:30%; float:right; padding:50px; border:solid black 1px' gm-on-drop="$ctrl.onDrop" gm-drop-zone='1'>Drops Allowed Here</div> | ||
``` | ||
## Handles | ||
You can add a child element to a `gm-draggable` element with the tag name or class `gm-drag-handle` to have it act as the drag 'handle' if you don't want the entire element to respond to dragging. | ||
### Sample template using a drag handle: | ||
```html | ||
<span gm-draggable="$ctrl.data"> | ||
<span class="gm-drag-handle">[Dragging only works if you click here]</span> Number {{data.value}} | ||
</span> | ||
``` | ||
## Demo | ||
http://plnkr.co/edit/FVCPTguyqL4ilh91VcNi?p=preview | ||
http://plnkr.co/edit/Gz4FuH?p=preview |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
8720
6
137
1
72