angular-file-uploader
Version:
Angular file uploader is an Angular 2/4/5/6/7/8/9/10/11/12/13 + file uploader module with Real-Time Progress Bar, Responsive design, Angular Universal Compatibility and multiple themes which includes Drag and Drop and much more.
300 lines (291 loc) • 19.2 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('/core'), require('@angular/common/http'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('angular-file-uploader', ['exports', '/core', '@angular/common/http', '@angular/common'], factory) :
(global = global || self, factory(global['angular-file-uploader'] = {}, global.ng.core, global.ng.common.http, global.ng.common));
}(this, (function (exports, core, http, common) { 'use strict';
var AngularFileUploaderComponent = /** @class */ (function () {
function AngularFileUploaderComponent(http) {
this.http = http;
this.resetUpload = false;
// Outputs
this.ApiResponse = new core.EventEmitter();
this.fileSelected = new core.EventEmitter();
this.allowedFiles = [];
this.notAllowedFiles = [];
this.Caption = [];
this.isAllowedFileSingle = true;
this.progressBarShow = false;
this.enableUploadBtn = false;
this.uploadMsg = false;
this.afterUpload = false;
this.uploadStarted = false;
this.currentUploads = [];
this.fileNameIndex = true;
this.withCredentials = false;
this.autoUpload = false;
this.idDate = +new Date();
}
AngularFileUploaderComponent.prototype.ngOnChanges = function (changes) {
// Track changes in Configuration and see if user has even provided Configuration.
if (changes.config && this.config) {
// Assign User Configurations to Library Properties.
this.theme = this.config.theme || '';
this.id =
this.config.id ||
parseInt((this.idDate / 10000).toString().split('.')[1], 10) +
Math.floor(Math.random() * 20) * 10000;
this.hideProgressBar = this.config.hideProgressBar || false;
this.hideResetBtn = this.config.hideResetBtn || false;
this.hideSelectBtn = this.config.hideSelectBtn || false;
this.maxSize = (this.config.maxSize || 20) * 1024000; // mb to bytes.
this.uploadAPI = this.config.uploadAPI.url;
this.method = this.config.uploadAPI.method || 'POST';
this.formatsAllowed = this.config.formatsAllowed || '*';
this.formatsAllowedText =
this.formatsAllowed === '*' ? '' : '(' + this.formatsAllowed + ')';
this.multiple = this.config.multiple || false;
this.headers = this.config.uploadAPI.headers || {};
this.params = this.config.uploadAPI.params || {};
this.responseType = this.config.uploadAPI.responseType || 'json';
this.withCredentials = this.config.uploadAPI.withCredentials || false;
this.fileNameIndex = this.config.fileNameIndex === false ? false : true;
this.autoUpload = this.config.autoUpload || false;
this.replaceTexts = {
selectFileBtn: this.multiple ? 'Select Files' : 'Select File',
resetBtn: 'Reset',
uploadBtn: 'Upload',
dragNDropBox: 'Drag N Drop',
attachPinBtn: this.multiple ? 'Attach Files...' : 'Attach File...',
afterUploadMsg_success: 'Successfully Uploaded !',
afterUploadMsg_error: 'Upload Failed !',
sizeLimit: 'Size Limit',
}; // default replaceText.
if (this.config.replaceTexts) {
// updated replaceText if user has provided any.
this.replaceTexts = Object.assign(Object.assign({}, this.replaceTexts), this.config.replaceTexts);
}
}
// Reset when resetUpload value changes from false to true.
if (changes.resetUpload) {
if (changes.resetUpload.currentValue === true) {
this.resetFileUpload();
}
}
};
// Reset following properties.
AngularFileUploaderComponent.prototype.resetFileUpload = function () {
this.allowedFiles = [];
this.Caption = [];
this.notAllowedFiles = [];
this.uploadMsg = false;
this.enableUploadBtn = false;
};
// When user selects files.
AngularFileUploaderComponent.prototype.onChange = function (event) {
this.fileSelected.emit(event);
this.notAllowedFiles = [];
var fileExtRegExp = /(?:\.([^.]+))?$/;
var fileList;
if (this.afterUpload || !this.multiple) {
this.allowedFiles = [];
this.Caption = [];
this.afterUpload = false;
}
if (event.type === 'drop') {
fileList = event.dataTransfer.files;
}
else {
fileList = event.target.files || event.srcElement.files;
}
// 'forEach' does not exist on 'filelist' that's why this good old 'for' is used.
for (var i = 0; i < fileList.length; i++) {
var currentFileExt = fileExtRegExp
.exec(fileList[i].name)[1]
.toLowerCase(); // Get file extension.
var isFormatValid = this.formatsAllowed.includes('*')
? true
: this.formatsAllowed.includes(currentFileExt);
var isSizeValid = fileList[i].size <= this.maxSize;
// Check whether current file format and size is correct as specified in the configurations.
if (isFormatValid && isSizeValid) {
this.allowedFiles.push(fileList[i]);
}
else {
this.notAllowedFiles.push({
fileName: fileList[i].name,
fileSize: this.convertSize(fileList[i].size),
errorMsg: !isFormatValid ? 'Invalid format' : 'Invalid size',
});
}
}
// If there's any allowedFiles.
if (this.allowedFiles.length > 0) {
this.enableUploadBtn = true;
// Upload the files directly if theme is attach pin (as upload btn is not there for this theme) or autoUpload is true.
if (this.theme === 'attachPin' || this.autoUpload) {
this.uploadFiles();
}
}
else {
this.enableUploadBtn = false;
}
this.uploadMsg = false;
this.uploadStarted = false;
this.uploadPercent = 0;
event.target.value = null;
};
AngularFileUploaderComponent.prototype.uploadFiles = function () {
var _this = this;
this.progressBarShow = true;
this.uploadStarted = true;
this.notAllowedFiles = [];
var isError = false;
this.isAllowedFileSingle = this.allowedFiles.length <= 1;
var formData = new FormData();
// Add data to be sent in this request
this.allowedFiles.forEach(function (file, i) {
formData.append(_this.Caption[i] || 'file' + (_this.fileNameIndex ? i : ''), _this.allowedFiles[i]);
});
/*
Not Working, Headers null
// Contruct Headers
const headers = new HttpHeaders();
for (const key of Object.keys(this.headers)) {
headers.append(key, this.headers[key]);
}
// Contruct Params
const params = new HttpParams();
for (const key of Object.keys(this.params)) {
params.append(key, this.params[key]);
} */
this.http
.request(this.method.toUpperCase(), this.uploadAPI, {
body: formData,
reportProgress: true,
observe: 'events',
headers: this.headers,
params: this.params,
responseType: this.responseType,
withCredentials: this.withCredentials,
})
.subscribe(function (event) {
// Upload Progress
if (event.type === http.HttpEventType.UploadProgress) {
_this.enableUploadBtn = false; // button should be disabled if process uploading
var currentDone = event.loaded / event.total;
_this.uploadPercent = Math.round((event.loaded / event.total) * 100);
}
else if (event.type === http.HttpEventType.Response) {
if (event.status === 200 || event.status === 201) {
// Success
_this.progressBarShow = false;
_this.enableUploadBtn = false;
_this.uploadMsg = true;
_this.afterUpload = true;
if (!isError) {
_this.uploadMsgText = _this.replaceTexts.afterUploadMsg_success;
_this.uploadMsgClass = 'text-success lead';
}
}
else {
// Failure
isError = true;
_this.handleErrors();
}
_this.ApiResponse.emit(event);
}
else {
//console.log('Event Other: ', event);
}
}, function (error) {
// Failure
isError = true;
_this.handleErrors();
_this.ApiResponse.emit(error);
});
};
AngularFileUploaderComponent.prototype.handleErrors = function () {
this.progressBarShow = false;
this.enableUploadBtn = false;
this.uploadMsg = true;
this.afterUpload = true;
this.uploadMsgText = this.replaceTexts.afterUploadMsg_error;
this.uploadMsgClass = 'text-danger lead';
};
AngularFileUploaderComponent.prototype.removeFile = function (i, sf_na) {
if (sf_na === 'sf') {
this.allowedFiles.splice(i, 1);
this.Caption.splice(i, 1);
}
else {
this.notAllowedFiles.splice(i, 1);
}
if (this.allowedFiles.length === 0) {
this.enableUploadBtn = false;
}
};
AngularFileUploaderComponent.prototype.convertSize = function (fileSize) {
return fileSize < 1024000
? (fileSize / 1024).toFixed(2) + ' KB'
: (fileSize / 1024000).toFixed(2) + ' MB';
};
AngularFileUploaderComponent.prototype.attachpinOnclick = function () {
var element = document.getElementById('sel' + this.id);
if (element !== null) {
element.click();
}
};
AngularFileUploaderComponent.prototype.drop = function (event) {
event.stopPropagation();
event.preventDefault();
this.onChange(event);
};
AngularFileUploaderComponent.prototype.allowDrop = function (event) {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
};
return AngularFileUploaderComponent;
}());
AngularFileUploaderComponent.decorators = [
{ type: core.Component, args: [{
selector: 'angular-file-uploader',
template: "<div class=\"container\" *ngIf=\"(theme !== 'attachPin')\" id=\"default\">\r\n\r\n <!-- Drag n Drop theme Starts -->\r\n <div *ngIf=\"theme == 'dragNDrop'\" id=\"dragNDrop\"\r\n [ngClass]=\"(hideSelectBtn && hideResetBtn) ? null : 'dragNDropBtmPad'\" class=\"dragNDrop\">\r\n <div style=\"position:relative;\">\r\n <div id=\"div1\" class=\"div1 afu-dragndrop-box\" (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\r\n <p class=\"afu-dragndrop-text\">{{replaceTexts?.dragNDropBox}}</p>\r\n </div>\r\n <!-- <span class='label label-info' id=\"upload-file-info{{id}}\">{{allowedFiles[0]?.name}}</span> -->\r\n </div>\r\n </div>\r\n <!-- Drag n Drop theme Ends -->\r\n\r\n <label for=\"sel{{id}}\" class=\"btn btn-primary btn-sm afu-select-btn\" [ngClass]=\"progressBarShow ? 'disabled' : null\"\r\n *ngIf=\"!hideSelectBtn\">{{replaceTexts?.selectFileBtn}}</label>\r\n <input type=\"file\" id=\"sel{{id}}\" style=\"display: none\" *ngIf=\"!hideSelectBtn\" [disabled]=\"progressBarShow\"\r\n (change)=\"onChange($event)\" title=\"Select file\" name=\"files[]\" [accept]=formatsAllowed\r\n [attr.multiple]=\"multiple ? '' : null\" />\r\n <button class=\"btn btn-info btn-sm resetBtn afu-reset-btn\" (click)=\"resetFileUpload()\" *ngIf=\"!hideResetBtn\"\r\n [disabled]=\"progressBarShow\">{{replaceTexts?.resetBtn}}</button>\r\n <br *ngIf=\"!hideSelectBtn\">\r\n <p class=\"constraints-info afu-constraints-info\">{{formatsAllowedText}} {{replaceTexts?.sizeLimit}}:\r\n {{(convertSize(maxSize))}}\r\n </p>\r\n <!--Allowed file list-->\r\n <div class=\"row afu-valid-file\" *ngFor=\"let sf of allowedFiles;let i=index\">\r\n <p class=\"col-xs-3 textOverflow\"><span class=\"text-primary\">{{sf.name}}</span></p>\r\n <p class=\"col-xs-3 padMarg sizeC\"><strong>({{convertSize(sf.size)}})</strong> </p>\r\n <!-- <input class=\"col-xs-3 progress caption\" type=\"text\" placeholder=\"Caption..\" [(ngModel)]=\"Caption[i]\" *ngIf=\"!uploadStarted\"/> -->\r\n <div class=\"progress col-xs-3 padMarg afu-progress-bar\"\r\n *ngIf=\"isAllowedFileSingle && progressBarShow && !hideProgressBar\">\r\n <span class=\"progress-bar progress-bar-success\" role=\"progressbar\"\r\n [ngStyle]=\"{'width':uploadPercent+'%'}\">{{uploadPercent}}%</span>\r\n </div>\r\n <a class=\"col-xs-1\" role=\"button\" (click)=\"removeFile(i,'sf')\" *ngIf=\"!uploadStarted\"><i\r\n class=\"fa fa-times\"></i></a>\r\n </div>\r\n <!--Not Allowed file list-->\r\n <div class=\"row text-danger afu-invalid-file\" *ngFor=\"let na of notAllowedFiles;let j=index\">\r\n <p class=\"col-xs-3 textOverflow\"><span>{{na['fileName']}}</span></p>\r\n <p class=\"col-xs-3 padMarg sizeC\"><strong>({{na['fileSize']}})</strong></p>\r\n <p class=\"col-xs-3 \">{{na['errorMsg']}}</p>\r\n <a class=\"col-xs-1 delFileIcon\" role=\"button\" (click)=\"removeFile(j,'na')\" *ngIf=\"!uploadStarted\"> <i\r\n class=\"fa fa-times\"></i></a>\r\n </div>\r\n\r\n <p *ngIf=\"uploadMsg\" class=\"{{uploadMsgClass}} + afu-upload-status\">{{uploadMsgText}}\r\n <p>\r\n <div *ngIf=\"!isAllowedFileSingle && progressBarShow && !hideProgressBar\">\r\n <div class=\"progress col-xs-4 padMarg afu-progress-bar\">\r\n <span class=\"progress-bar progress-bar-success\" role=\"progressbar\"\r\n [ngStyle]=\"{'width':uploadPercent+'%'}\">{{uploadPercent}}%</span>\r\n </div>\r\n <br>\r\n <br>\r\n </div>\r\n <button class=\"btn btn-success afu-upload-btn\" type=\"button\" (click)=\"uploadFiles()\"\r\n [disabled]=\"!enableUploadBtn && progressBarShow\" *ngIf=\"!autoUpload\">{{replaceTexts?.uploadBtn}}</button>\r\n <br>\r\n</div>\r\n\r\n<!--/////////////////////////// ATTACH PIN THEME //////////////////////////////////////////////////////////-->\r\n<div *ngIf=\"theme == 'attachPin'\" id=\"attachPin\">\r\n <div style=\"position:relative;padding-left:6px\">\r\n <a class='btn up_btn afu-attach-pin' (click)=\"attachpinOnclick()\">\r\n {{replaceTexts?.attachPinBtn}}\r\n <i class=\"fa fa-paperclip\" aria-hidden=\"true\"></i>\r\n <!-- <p style=\"margin-top:10px\">({{formatsAllowedText}}) Size limit- {{(convertSize(maxSize))}}</p> -->\r\n <input type=\"file\" id=\"sel{{id}}\" (change)=\"onChange($event)\" style=\"display: none\" title=\"Select file\"\r\n name=\"files[]\" [accept]=formatsAllowed [attr.multiple]=\"multiple ? '' : null\" />\r\n <br>\r\n </a>\r\n \r\n <span class='label label-info' id=\"upload-file-info{{id}}\">{{allowedFiles[0]?.name}}</span>\r\n </div>\r\n</div>",
styles: [".constraints-info{font-style:italic;margin-top:10px}.padMarg{margin-bottom:0;padding:0}.caption{margin-right:5px}.textOverflow{overflow:hidden;padding-right:0;text-overflow:ellipsis;white-space:nowrap}.up_btn{background-color:transparent;border:2px solid #5c5b5b;border-radius:22px;color:#000}.delFileIcon{color:#ce0909;text-decoration:none}.selectBtnDisabled{background-color:#ccc;border:1px solid #999;color:#666;cursor:no-drop}.dragNDrop .div1{border:2px dashed #5c5b5b;display:border-box;height:6rem;width:20rem}.dragNDrop .div1>p{color:#5c5b5b;font-weight:700;margin-top:1.4em;text-align:center}.dragNDropBtmPad{padding-bottom:2rem}@media screen and (max-width:620px){.caption{padding:0}}@media screen and (max-width:510px){.sizeC{width:25%}}@media screen and (max-width:260px){.caption,.sizeC{font-size:10px}}.resetBtn{margin-left:3px}"]
},] }
];
AngularFileUploaderComponent.ctorParameters = function () { return [
{ type: http.HttpClient, decorators: [{ type: core.SkipSelf }] }
]; };
AngularFileUploaderComponent.propDecorators = {
config: [{ type: core.Input }],
resetUpload: [{ type: core.Input }],
ApiResponse: [{ type: core.Output }],
fileSelected: [{ type: core.Output }]
};
var AngularFileUploaderModule = /** @class */ (function () {
function AngularFileUploaderModule() {
}
return AngularFileUploaderModule;
}());
AngularFileUploaderModule.decorators = [
{ type: core.NgModule, args: [{
imports: [
common.CommonModule,
http.HttpClientModule,
],
declarations: [AngularFileUploaderComponent],
exports: [AngularFileUploaderComponent]
},] }
];
/*
* Public API Surface of angular-file-uploader
*/
/**
* Generated bundle index. Do not edit.
*/
exports.AngularFileUploaderComponent = AngularFileUploaderComponent;
exports.AngularFileUploaderModule = AngularFileUploaderModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=angular-file-uploader.umd.js.map