diff --git a/bower.json b/bower.json index 42de338..b4ff190 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,7 @@ "author": "Louis Sivillo", "name": "angular-file-dnd", "description": "AngularJS directive leveraging HTML5 Drag and Drop and the FileReader API", - "version": "1.0.4", + "version": "1.1.0", "main": "dist/angular-file-dnd.min.js", "dependencies": { "angular": "~1.2.0" diff --git a/dist/angular-file-dnd.js b/dist/angular-file-dnd.js index 1a88cf4..6370a70 100644 --- a/dist/angular-file-dnd.js +++ b/dist/angular-file-dnd.js @@ -4,20 +4,19 @@ return { require: '^?form', restrict: 'A', - scope: { - file: '=', - fileName: '=', - dropzoneHoverClass: '@' - }, + scope: false, link: function(scope, element, attrs, form) { - var checkSize, getDataTransfer, isTypeValid, processDragOverOrEnter, validMimeTypes; + var checkSize, getDataTransfer, isTypeValid, processDragOverOrEnter, setScopeVar, validMimeTypes; getDataTransfer = function(event) { var dataTransfer; return dataTransfer = event.dataTransfer || event.originalEvent.dataTransfer; }; processDragOverOrEnter = function(event) { + if (!scope.$eval(attrs.dropzoneEnabled)) { + return true; + } if (event) { - element.addClass(scope.dropzoneHoverClass); + element.addClass(attrs.dropzoneHoverClass); if (event.preventDefault) { event.preventDefault(); } @@ -28,6 +27,7 @@ getDataTransfer(event).effectAllowed = 'copy'; return false; }; + attrs.dropzoneHoverClass = attrs.dropzoneHoverClass || 'file-droping'; validMimeTypes = attrs.fileDropzone; checkSize = function(size) { var _ref; @@ -46,31 +46,45 @@ return false; } }; + setScopeVar = function(name, value) { + var objName, tmp, varName; + if (name.indexOf('.') === -1) { + return scope[name] = value; + } else { + tmp = name.split('.'); + objName = tmp.slice(0, -1).join('.'); + varName = tmp[tmp.length - 1]; + return scope.$eval(objName)[varName] = value; + } + }; element.bind('dragover', processDragOverOrEnter); element.bind('dragenter', processDragOverOrEnter); element.bind('dragleave', function() { - return element.removeClass(scope.dropzoneHoverClass); + return element.removeClass(attrs.dropzoneHoverClass); }); return element.bind('drop', function(event) { var file, name, reader, size, type; + if (!scope.$eval(attrs.dropzoneEnabled)) { + return true; + } if (event != null) { event.preventDefault(); } - element.removeClass(scope.dropzoneHoverClass); + element.removeClass(attrs.dropzoneHoverClass); reader = new FileReader(); reader.onload = function(evt) { if (checkSize(size) && isTypeValid(type)) { scope.$apply(function() { - scope.file = evt.target.result; - if (angular.isString(scope.fileName)) { - return scope.fileName = name; + setScopeVar(attrs.file, evt.target.result); + if (angular.isString(attrs.fileName)) { + return setScopeVar(attrs.fileName, name); } }); if (form) { form.$setDirty(); } return scope.$emit('file-dropzone-drop-event', { - file: scope.file, + file: scope[attrs.file], type: type, name: name, size: size @@ -81,7 +95,22 @@ name = file.name; type = file.type; size = file.size; - reader.readAsDataURL(file); + if (!angular.isDefined(attrs.asFile)) { + reader.readAsDataURL(file); + } else { + scope.$apply(function() { + setScopeVar(attrs.file, file); + if (angular.isString(attrs.fileName)) { + return setScopeVar(attrs.fileName, name); + } + }); + if (form) { + form.$setDirty(); + } + scope.$emit('file-dropzone-drop-event', { + file: file + }); + } return false; }); } diff --git a/dist/angular-file-dnd.min.js b/dist/angular-file-dnd.min.js index 83016ab..8200d5c 100644 --- a/dist/angular-file-dnd.min.js +++ b/dist/angular-file-dnd.min.js @@ -1 +1 @@ -(function(){"use strict";angular.module("omr.angularFileDnD",[]).directive("fileDropzone",function(){return{require:"^?form",restrict:"A",scope:{file:"=",fileName:"=",dropzoneHoverClass:"@"},link:function(a,b,c,d){var e,f,g,h,i;return f=function(a){var b;return b=a.dataTransfer||a.originalEvent.dataTransfer},h=function(c){return c&&(b.addClass(a.dropzoneHoverClass),c.preventDefault&&c.preventDefault(),c.stopPropagation)?!1:(f(c).effectAllowed="copy",!1)},i=c.fileDropzone,e=function(a){var b;return void 0===(b=c.maxFileSize)||""===b||a/1024/1024-1?!0:(alert("Invalid file type. File must be one of following types "+i),!1)},b.bind("dragover",h),b.bind("dragenter",h),b.bind("dragleave",function(){return b.removeClass(a.dropzoneHoverClass)}),b.bind("drop",function(c){var h,i,j,k,l;return null!=c&&c.preventDefault(),b.removeClass(a.dropzoneHoverClass),j=new FileReader,j.onload=function(b){return e(k)&&g(l)?(a.$apply(function(){return a.file=b.target.result,angular.isString(a.fileName)?a.fileName=i:void 0}),d&&d.$setDirty(),a.$emit("file-dropzone-drop-event",{file:a.file,type:l,name:i,size:k})):void 0},h=f(c).files[0],i=h.name,l=h.type,k=h.size,j.readAsDataURL(h),!1})}}})}).call(this); \ No newline at end of file +(function(){"use strict";angular.module("omr.angularFileDnD",[]).directive("fileDropzone",function(){return{require:"^?form",restrict:"A",scope:!1,link:function(a,b,c,d){var e,f,g,h,i,j;return f=function(a){var b;return b=a.dataTransfer||a.originalEvent.dataTransfer},h=function(d){return a.$eval(c.dropzoneEnabled)?d&&(b.addClass(c.dropzoneHoverClass),d.preventDefault&&d.preventDefault(),d.stopPropagation)?!1:(f(d).effectAllowed="copy",!1):!0},c.dropzoneHoverClass=c.dropzoneHoverClass||"file-droping",j=c.fileDropzone,e=function(a){var b;return void 0===(b=c.maxFileSize)||""===b||a/1024/1024-1?!0:(alert("Invalid file type. File must be one of following types "+j),!1)},i=function(b,c){var d,e,f;return-1===b.indexOf(".")?a[b]=c:(e=b.split("."),d=e.slice(0,-1).join("."),f=e[e.length-1],a.$eval(d)[f]=c)},b.bind("dragover",h),b.bind("dragenter",h),b.bind("dragleave",function(){return b.removeClass(c.dropzoneHoverClass)}),b.bind("drop",function(h){var j,k,l,m,n;return a.$eval(c.dropzoneEnabled)?(null!=h&&h.preventDefault(),b.removeClass(c.dropzoneHoverClass),l=new FileReader,l.onload=function(b){return e(m)&&g(n)?(a.$apply(function(){return i(c.file,b.target.result),angular.isString(c.fileName)?i(c.fileName,k):void 0}),d&&d.$setDirty(),a.$emit("file-dropzone-drop-event",{file:a[c.file],type:n,name:k,size:m})):void 0},j=f(h).files[0],k=j.name,n=j.type,m=j.size,angular.isDefined(c.asFile)?(a.$apply(function(){return i(c.file,j),angular.isString(c.fileName)?i(c.fileName,k):void 0}),d&&d.$setDirty(),a.$emit("file-dropzone-drop-event",{file:j})):l.readAsDataURL(j),!1):!0})}}})}).call(this); \ No newline at end of file diff --git a/package.json b/package.json index fd08d7f..75b0355 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-file-dnd", - "version": "1.0.4", + "version": "1.1.0", "dependencies": {}, "devDependencies": { "grunt": "~0.4.1", diff --git a/src/directive/file_dropzone.coffee b/src/directive/file_dropzone.coffee index 7f48d0e..efcf9ab 100644 --- a/src/directive/file_dropzone.coffee +++ b/src/directive/file_dropzone.coffee @@ -4,11 +4,7 @@ angular.module('omr.angularFileDnD', []) .directive('fileDropzone', () -> require: '^?form' restrict: 'A' - scope: { - file: '=' - fileName: '=' - dropzoneHoverClass: '@' - } + scope: false, link: (scope, element, attrs, form) -> getDataTransfer = (event) -> @@ -16,13 +12,17 @@ angular.module('omr.angularFileDnD', []) # function to prevent default behavior (browser loading image) processDragOverOrEnter = (event) -> + if !scope.$eval(attrs.dropzoneEnabled) + return true + if event - element.addClass scope.dropzoneHoverClass + element.addClass attrs.dropzoneHoverClass event.preventDefault() if event.preventDefault return false if event.stopPropagation getDataTransfer(event).effectAllowed = 'copy' false + attrs.dropzoneHoverClass = attrs.dropzoneHoverClass || 'file-droping'; validMimeTypes = attrs.fileDropzone # if the max file size is provided and the size of dropped file is greater than it, @@ -42,33 +42,54 @@ angular.module('omr.angularFileDnD', []) alert "Invalid file type. File must be one of following types #{validMimeTypes}" false + setScopeVar = (name, value) -> + if name.indexOf('.') == -1 + scope[name] = value + else + tmp = name.split('.') + objName = tmp.slice(0, -1).join('.') + varName = tmp[tmp.length - 1] + scope.$eval(objName)[varName] = value + # for dragover and dragenter (IE) we stop the browser from handling the # event and specify copy as the allowable effect element.bind 'dragover', processDragOverOrEnter element.bind 'dragenter', processDragOverOrEnter element.bind 'dragleave', -> - element.removeClass scope.dropzoneHoverClass + element.removeClass attrs.dropzoneHoverClass # on drop events we stop browser and read the dropped file via the FileReader # the resulting droped file is bound to the image property of the scope of this directive element.bind 'drop', (event) -> + if !scope.$eval(attrs.dropzoneEnabled) + return true + event?.preventDefault() - element.removeClass scope.dropzoneHoverClass + element.removeClass attrs.dropzoneHoverClass reader = new FileReader() reader.onload = (evt) -> if checkSize(size) and isTypeValid(type) scope.$apply -> - scope.file = evt.target.result - scope.fileName = name if angular.isString scope.fileName + setScopeVar(attrs.file, evt.target.result) + setScopeVar(attrs.fileName, name) if angular.isString attrs.fileName if form form.$setDirty() #notify the form of this change - scope.$emit 'file-dropzone-drop-event', {file: scope.file, type: type, name: name, size: size} + scope.$emit 'file-dropzone-drop-event', {file: scope[attrs.file], type: type, name: name, size: size} file = getDataTransfer(event).files[0] name = file.name type = file.type size = file.size - reader.readAsDataURL file + if !angular.isDefined(attrs.asFile) + reader.readAsDataURL file + else + scope.$apply -> + setScopeVar(attrs.file, file) + setScopeVar(attrs.fileName, name) if angular.isString attrs.fileName + if form + form.$setDirty() #notify the form of this change + scope.$emit 'file-dropzone-drop-event', {file: file} + false )