Streamlines image upload directives for more re-use, creates umbImageUpload directive which is a wrapper for the blueimp file-upload directive which allows us to have a directive that exposes an API (which the blue imp does not do), creates new upload progress directive so that can easily be re-used inside of any umbimageupload directive.

This commit is contained in:
Shannon
2015-02-12 14:40:15 +11:00
parent 8af8a6d411
commit 7d17aef953
4 changed files with 87 additions and 36 deletions

View File

@@ -14,9 +14,7 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
nodeId: '@',
onUploadComplete: '='
},
link: function (scope, element, attrs) {
//NOTE: Blueimp handlers are documented here: https://github.com/blueimp/jQuery-File-Upload/wiki/Options
//NOTE: We are using a Blueimp version specifically ~9.4.0 because any higher than that and we get crazy errors with jquery, also note
// that the jquery UI version 1.10.3 is required for this blueimp version! if we go higher to 1.10.4 it breaks! seriously!
@@ -25,7 +23,7 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
if (scope.onUploadComplete && !angular.isFunction(scope.onUploadComplete)) {
throw "onUploadComplete must be a function callback";
}
scope.uploading = false;
scope.files = [];
scope.progress = 0;
@@ -38,9 +36,9 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
.test(window.navigator.userAgent),
previewMaxWidth: 150,
previewMaxHeight: 150,
previewCrop: true,
previewCrop: true,
dropZone: element.find(".drop-zone"),
formData : {
formData: {
currentFolder: scope.nodeId
}
};
@@ -55,34 +53,28 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
});
}
//tracks the total file progress
scope.$on('fileuploadprogressall', function (e, data) {
scope.$apply(function () {
scope.progress = parseInt(data.loaded / data.total * 100, 10);
});
});
//when one is finished
scope.$on('fileuploaddone', function (e, data) {
scope.$apply(function () {
scope.$on('fileuploaddone', function(e, data) {
scope.$apply(function() {
//remove the amount of files complete
//NOTE: function is here instead of in the loop otherwise jshint blows up
function findFile (file) { return file === data.files[i]; }
function findFile(file) { return file === data.files[i]; }
for (var i = 0; i < data.files.length; i++) {
var found = _.find(scope.files, findFile);
found.completed = true;
}
//when none are left resync everything
var remaining = _.filter(scope.files, function (file) { return file.completed !== true; });
var remaining = _.filter(scope.files, function(file) { return file.completed !== true; });
if (remaining.length === 0) {
scope.progress = 100;
//just the ui transition isn't too abrupt, just wait a little here
$timeout(function () {
$timeout(function() {
scope.progress = 0;
scope.files = [];
scope.uploading = false;
@@ -103,8 +95,8 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
//This handler gives us access to the file 'preview', this is the only handler that makes this available for whatever reason
// so we'll use this to also perform the adding of files to our collection
scope.$on('fileuploadprocessalways', function (e, data) {
scope.$apply(function () {
scope.$on('fileuploadprocessalways', function(e, data) {
scope.$apply(function() {
scope.uploading = true;
scope.files.push(data.files[data.index]);
});
@@ -112,22 +104,23 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
//This executes prior to the whole processing which we can use to get the UI going faster,
//this also gives us the start callback to invoke to kick of the whole thing
scope.$on('fileuploadadd', function (e, data) {
scope.$apply(function () {
scope.$on('fileuploadadd', function(e, data) {
scope.$apply(function() {
scope.uploading = true;
});
});
// All these sit-ups are to add dropzone area and make sure it gets removed if dragging is aborted!
scope.$on('fileuploaddragover', function (e, data) {
scope.$on('fileuploaddragover', function(e, data) {
if (!scope.dragClearTimeout) {
scope.$apply(function () {
scope.$apply(function() {
scope.dropping = true;
});
} else {
}
else {
$timeout.cancel(scope.dragClearTimeout);
}
scope.dragClearTimeout = $timeout(function () {
scope.dragClearTimeout = $timeout(function() {
scope.dropping = null;
scope.dragClearTimeout = null;
}, 300);
@@ -135,6 +128,7 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
//init load
loadChildren(scope.nodeId);
}
};
}

View File

@@ -0,0 +1,39 @@
/**
* @ngdoc directive
* @name umbraco.directives.directive:umbImageFileUpload
* @restrict E
* @function
* @description
* This is a wrapper around the blueimp angular file-upload directive so that we can expose a proper API to other directives, the blueimp
* directive isn't actually made very well and only exposes an API/events on the $scope so we can't do things like require: "^fileUpload" and use
* it's instance.
**/
function umbImageUpload($compile) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
//set inner scope variable to assign to file-upload directive in the template
scope.innerOptions = scope.$eval(attrs.umbImageUpload);
//compile an inner blueimp file-upload with our scope
var x = angular.element('<div file-upload="innerOptions" />');
element.append(x);
$compile(x)(scope);
},
//Define a controller for this directive to expose APIs to other directives
controller: function ($scope, $element, $attrs) {
//create a method to allow binding to a blueimp event (which is based on it's directives scope)
this.bindEvent = function (e, callback) {
$scope.$on(e, callback);
};
}
};
}
angular.module("umbraco.directives").directive('umbImageUpload', umbImageUpload);

View File

@@ -0,0 +1,23 @@
/**
* @ngdoc directive
* @name umbraco.directives.directive:umbImageUploadProgress
* @restrict E
* @function
**/
function umbImageUploadProgress($rootScope, assetsService, $timeout, $log, umbRequestHelper, mediaResource, imageHelper) {
return {
require: '^umbImageUpload',
restrict: 'E',
replace: true,
template: '<div class="progress progress-striped active"><div class="bar" ng-style="{width: uploadProgress + \'%\'}"></div></div>',
link: function (scope, element, attrs, umbImgUploadCtrl) {
umbImgUploadCtrl.bindEvent('fileuploadprogressall', function (e, data) {
scope.uploadProgress = parseInt(data.loaded / data.total * 100, 10);
});
}
};
}
angular.module("umbraco.directives").directive('umbImageUploadProgress', umbImageUploadProgress);

View File

@@ -1,8 +1,5 @@
<form ng-controller="Umbraco.PropertyEditors.FolderBrowserController" id="fileupload"
style="width: 100%"
method="POST" enctype="multipart/form-data"
class="umb-editor umb-folderbrowser"
file-upload="blueimpOptions">
<form style="width: 100%" method="POST" enctype="multipart/form-data" class="umb-editor umb-folderbrowser"
umb-image-upload="blueimpOptions">
<div class="drop-zone">
@@ -15,9 +12,8 @@
<umb-upload-dropzone ng-show="dropping && !uploading"></umb-upload-dropzone>
<div ng-if="uploading">
<div class="progress progress-striped active">
<div class="bar" ng-style="{width: progress + '%'}"></div>
</div>
<umb-image-upload-progress></umb-image-upload-progress>
<div class="umb-photo-preview"
ng-repeat="file in files"
@@ -35,5 +31,4 @@
on-click="clickHandler"
ng-model="images" />
</form>