Last active
August 29, 2015 14:19
-
-
Save alexisnomine/04d1c7ab3f1de1b8ea3e to your computer and use it in GitHub Desktop.
AngularJS File Drag & Drop directive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
angular.module('ngFileDND', ['ng']) | |
.directive('dropZone', function () { | |
return { | |
restrict: 'E', | |
scope: { | |
message: '@', | |
accept: '@', | |
file: '=', | |
filename: '=' | |
}, | |
template: '<p>{{ message }}</p><form name="fileInputForm"><input type="file" name="file" accept="{{ accept }}" style="visibility:hidden"></form>', | |
link: function (scope, element, attrs) { | |
var dropzone = element[0]; | |
var fileInputForm = dropzone.querySelector('[name=fileInputForm]'); | |
dropzone.addEventListener('dragenter', function (e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
this.classList.add('over'); | |
}, false); | |
dropzone.addEventListener('dragleave', function (e) { | |
// removes class only if we're not in the dropzone anymore | |
// (this event gets also fired when we're over the <p> element in the dropzone) | |
var rect = this.getBoundingClientRect(); | |
if (e.clientX > rect.left + rect.width || e.clientX < rect.left || e.clientY > rect.top + rect.height || e.clientY < rect.top) { | |
this.classList.remove('over'); | |
} | |
}, false); | |
dropzone.addEventListener('dragover', function (e) { | |
e.preventDefault(); | |
e.dataTransfer.dropEffect = 'copy'; | |
}, false); | |
// traitement automatique de l'image dès qu'elle est déposée | |
dropzone.addEventListener('drop', function (e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
this.classList.remove('over'); | |
// lecture du fichier | |
readFile(e.dataTransfer.files); | |
}, false); | |
// curseur "clic" lorsqu'on est au dessus de la zone | |
dropzone.addEventListener('mouseover', function (e) { | |
this.style.cursor = 'pointer'; | |
}, false); | |
// ouverture de la boite de dialogue de sélection du fichier | |
dropzone.addEventListener('click', function (e) { | |
fileInputForm.file.click(); | |
}, false); | |
// traitement automatique de l'image dès qu'elle est sélectionnée | |
fileInputForm.addEventListener('change', function (e) { | |
// lecture du fichier | |
readFile(fileInputForm.file.files); | |
// efface le contenu de l'input file | |
var files = fileInputForm.reset(); | |
}, false); | |
// lecture du fichier | |
function readFile(files) { | |
// traitement lancé uniquement si on a un fichier au bon format | |
if (files.length > 0 && $.inArray(files[0].type, attrs.accept.split(/, ?/)) != -1) { | |
// lecture du fichier | |
var reader = new FileReader(); | |
reader.onloadend = function () { | |
// met à jour la variable passée en paramètre ('file') avec le contenu du fichier | |
scope.$apply(function () { | |
scope.file = reader.result; | |
}); | |
} | |
reader.readAsDataURL(files[0]); | |
// met à jour la variable passée en paramètre ('filename') avec le nom de l'image sans l'extension | |
scope.filename = files[0].name.substring(0, files[0].name.lastIndexOf('.')); | |
} | |
} | |
} | |
}; | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment