UNPKG

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
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('@angular/common')) : typeof define === 'function' && define.amd ? define('angular-file-uploader', ['exports', '@angular/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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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\">&nbsp;<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 &nbsp;\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