Skip to content

Instantly share code, notes, and snippets.

@chrisirhc
Created January 23, 2014 02:29
Show Gist options
  • Save chrisirhc/8571779 to your computer and use it in GitHub Desktop.
Save chrisirhc/8571779 to your computer and use it in GitHub Desktop.
HTML5 draggable/drop AngularJS directives
.directive("teDragitem5", [
'$parse',
function ($parse) {
return {
link: function (scope, element, attr) {
var dragElement = element;
// Many other quirks in IE9. Not worth solving.
// teDragitem wraps the current element in an anchor element for
// IE9 as IE9 only supports draggable link elements. This
// behavior is undesirable in other browsers as other browsers
// (e.g. Chrome) treat dragging link elements differently.
// if (!element.is('a') &&
// jQuery && jQuery.browser && jQuery.browser.msie) {
// element.wrap('<a href="#"></a>');
// dragElement = element.parent();
// dragElement.bind('click',function (event) {
// event.preventDefault();
// });
// }
scope.teDragitemDragging = false;
var effectAllowedFn = $parse(attr.teDragitemEffectallowed);
var dragStartFn = $parse(attr.teDragitemDragstart);
var dragEndFn = $parse(attr.teDragitemDragend);
var dragitemData;
scope.$watch(attr.teDragitem, function (value) {
if (value) {
element.attr('draggable', 'true');
dragitemData = value;
} else {
element.removeAttr('draggable');
dragitemData = undefined;
}
}, true);
dragElement.bind('selectstart', function (event) {
event.preventDefault();
});
// Remove all selections when before starting to drag
// dragElement.bind('mousedown', function () {
// if ($window.getSelection) {
// $window.getSelection().removeAllRanges();
// }
// });
dragElement.bind('dragstart', function (event) {
if (!dragitemData) return;
setEventDataTransfer(event);
scope.$apply(isDragging);
});
dragElement.bind('dragend', function () {
scope.$apply(isNotDragging);
});
function setEventDataTransfer(event) {
var effectAllowed = effectAllowedFn(scope, {
event: event,
data: dragitemData
});
if (typeof effectAllowed == 'string') {
event.originalEvent.dataTransfer.effectAllowed =
effectAllowed;
} else {
event.originalEvent.dataTransfer.effectAllowed =
'move';
}
// IE9 doesn't support 'application/json' as data format
event.originalEvent.dataTransfer.setData(
'Text',
angular.toJson(dragitemData)
);
}
function isDragging() {
scope.teDragitemDragging = true;
dragStartFn();
}
function isNotDragging() {
scope.teDragitemDragging = false;
dragEndFn();
}
}
};
}
])
.directive("teDropzone5", [
'$parse',
function ($parse) {
return {
link: function ( scope, element, attr ) {
var dropFn = $parse(attr.teDropzone);
var dropEffectFn;
if (attr.teDropzoneEffect) {
dropEffectFn = $parse(attr.teDropzoneEffect);
}
scope.teDropzoneOver = false;
// IE9 doesn't support 'application/json' as data format
// http://msdn.microsoft.com/en-us/library/ie/ms536744(v=vs.85).aspx
element.bind('drop', function ( event ) {
var dataText =
event.originalEvent.dataTransfer.getData('Text');
var data;
if (dataText) {
try {
data = angular.fromJson(dataText);
} catch (e) {
// Fail silently
}
}
scope.$apply(function() {
dropFn(scope, {
event: event,
data: data
});
isNotOver();
});
});
// Just for you, IE.
element.bind('dragenter', function (event) {
event.preventDefault();
});
element.bind('dragover', function (event) {
// Note that getData doesn't work within this event for
// webkit
var dropEffect = !dropEffectFn || dropEffectFn(scope, {
event: event
});
if (dropEffect) {
if (typeof dropEffect == 'string') {
event.originalEvent.dataTransfer.dropEffect =
dropEffect;
} else {
// Defaults to move
event.originalEvent.dataTransfer.dropEffect =
'move';
}
event.preventDefault();
scope.$apply(isOver);
}
});
element.bind('dragleave', function () {
scope.$apply(isNotOver);
});
function isOver() {
scope.teDropzoneOver = true;
}
function isNotOver() {
scope.teDropzoneOver = false;
}
}
};
}
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment