Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Last active July 29, 2017 15:37
Show Gist options
  • Save kentcdodds/8bfdbf832b3cebfb050f to your computer and use it in GitHub Desktop.
Save kentcdodds/8bfdbf832b3cebfb050f to your computer and use it in GitHub Desktop.
upload-file

upload-file angular-formly type

This is my upload-file type for what I use at work. We use angular-upload for the upload service to do the actual file uploading. We also have several abstractions and use ES6 that may confuse you a little bit (sorry about that). Hopefully this gets you started though.

export default ngModule => {
ngModule.directive('azFileUploadInput', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
azFileUploadInput: '='
},
link(scope, element) {
element.on('change', function(e) {
if (!e.target.files || !e.target.files[0]) {
return;
}
scope.azFileUploadInput = e.target.files[0].name;
scope.$apply();
});
}
};
});
};
<div class="upload-file no-padding">
<div class="upload-file__fileinput-area">
<input class="form-control --exception upload-file__fileinput-area__fileupload"
name="{{::id}}"
type="file"
data-sequential-uploads="true"
ng-model="fileToUpload"
az-file-upload-input="fileUploadName">
<input class="form-control --exception"
placeholder="{{::to.placeholder}}"
type="text"
value="{{fileUploadName}}"
data-sequential-uploads="true"
disabled="disabled">
</div>
<button
class="upload-file__button btn btn-default az-btn hide-when-readonly"
ng-click="startUpload()"
ng-if="!to.noButton"
az-loading-button="uploading"
ng-disabled="!fileUploadName">
<span ng-bind-html="::buttonContents"></span>
</button>
</div>
export default ngModule => {
ngModule.run(function(formlyConfig) {
formlyConfig.setType({
name: 'upload-file',
template: require('./upload-file.html'),
extends: 'azBase',
data: {
styles: require('./upload-file.less')
},
defaultOptions: {
data: {
noTouchy: true
}
},
controller: /* @ngInject */ function($scope, upload, $sce, notify, NotifyInterceptor, _) {
$scope.startUpload = startUpload;
$scope.options.data.startUpload = startUpload;
$scope.buttonContents = $sce.trustAsHtml($scope.to.uploadButtonHtml);
function startUpload() {
if (!$scope.fileInputEl.val()) {
notify.warning('File Not Uploaded', 'Please choose a file to upload');
return undefined;
}
$scope.uploading = upload({
url: $scope.to.url,
method: 'POST',
headers: {
'Accept': '*/*'
},
data: {
file: $scope.fileInputEl
},
azData: {
notifications: {error: null},
analytics: {
eventType: 'file-upload',
category: 'FILE_UPLOAD'
}
}
}).then(function successHandler(response) {
// Remove any previous errors
$scope.to.fileUploadErrors = null;
var successMessage = $scope.to.successMessage;
if (_.isFunction(successMessage)) {
successMessage = successMessage(response);
}
if (successMessage !== null) {
notify.success(successMessage || 'File uploaded successfully');
}
if ($scope.to.onSuccess) {
return $scope.to.onSuccess(response, $scope.options, $scope);
} else {
return response;
}
}, function errorHandler(response) {
if (response.data && _.isArray(response.data) && !_.isUndefined(response.data[0].lineNumber)) {
$scope.to.fileUploadErrors = response.data;
var errorMessage = $scope.to.errorMessage;
if (_.isFunction(errorMessage)) {
errorMessage = errorMessage(response);
}
if (errorMessage) {
notify.error('Upload failed', errorMessage);
}
} else {
delete response.config.azData.notifications.error;
NotifyInterceptor.responseError(response);
}
throw response;
});
return $scope.uploading;
}
},
link: function(scope, el) {
var int = setInterval(function() {
scope.fileInputEl = el.find('input[type=file]');
if (scope.fileInputEl.length) {
clearInterval(int);
}
}, 10);
}
});
});
};
.component(upload-file, {
height: 34px;
display: flex;
.part(fileinput-area, {
position: relative;
overflow: hidden;
flex: 1;
.part(fileupload, {
opacity: 0;
position: absolute;
z-index: 1;
});
});
.part(button, {
margin-left: 20px;
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment