Skip to content

Instantly share code, notes, and snippets.

@tnqsoft
Last active August 24, 2017 07:25
Show Gist options
  • Save tnqsoft/aea7d0caeb88399ce652ef81106f3247 to your computer and use it in GitHub Desktop.
Save tnqsoft/aea7d0caeb88399ce652ef81106f3247 to your computer and use it in GitHub Desktop.
Angular 4 with ng2-file-upload
import { FileUploadModule } from 'ng2-file-upload';
import { ThumbnailDirective } from './thumbnail.directive';
...
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
CommonModule,
FileUploadModule
],
<button class="btn btn-default" (click)="uploadField.addFile()" [disabled]="uploadField.isMaxFile()">
Add File
</button>
<app-upload-field
[maxFileSize]="1*1024*1024"
[maxFile]="3"
[multiple]="false"
[accept]="['image/png', 'image/gif', 'image/jpeg', 'image/jpg', 'image/bmp', 'text/plain', 'text/csv', 'application/pdf', 'application/zip']"
[errorMessageMaxSize]="'File size great than 1MB'"
[errorMessageWrongType]="'Not allow file format'"
[errorMessageLimit]="'Maximum files'"
(onItemChanged)="uploadFieldChanged($event)"
></app-upload-field>
import { Component, OnInit, OnDestroy, Inject, ViewChild } from '@angular/core';
import { UploadFieldComponent } from './upload-field.component';
@Component({
selector: 'app-demo',
templateUrl: 'demo.component.html',
})
export class ContactSendMessageComponent implements OnInit, OnDestroy {
@ViewChild(UploadFieldComponent) public uploadField: UploadFieldComponent;
constructor() {}
public ngOnInit() {
}
/**
* Submit Form
*
* @param {*} data
*/
public submit(data: any): void {
if (this.form.valid) {
let formData: FormData = this.buildRequestData(data);
// Call api post
} else {
this.formSubmited = true;
}
}
/**
* Build request data
*
* @private
* @param {*} data
* @returns {FormData}
*/
private buildRequestData(data: any): FormData {
let formData: FormData = new FormData();
formData.append('test', 'value');
// Add file to form
let files: Array<any> = this.uploadField.getFiles();
files.forEach(file => {
formData.append('files[]', file, file.name);
});
return formData;
}
}
import { Directive, ElementRef, Input, Renderer, OnChanges, SimpleChanges } from '@angular/core';
@Directive({
selector: 'img[thumbnail]'
})
export class ThumbnailDirective {
@Input() public image: any;
constructor(private el: ElementRef, private renderer: Renderer) { }
public ngOnChanges(changes: SimpleChanges) {
let reader = new FileReader();
let el = this.el;
reader.onloadend = (readerEvent) => {
let image = new Image();
image.onload = (imageEvent) => {
// Resize the image
let canvas = document.createElement('canvas');
let maxSize = 70;
let width = image.width;
let height = image.height;
if (width > height) {
if (width > maxSize) {
height *= maxSize / width;
width = maxSize;
}
} else {
if (height > maxSize) {
width *= maxSize / height;
height = maxSize;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
el.nativeElement.src = canvas.toDataURL('image/jpeg');
};
image.src = reader.result;
};
if (this.image) {
return reader.readAsDataURL(this.image);
}
}
}
<div *ngFor="let item of uploader.queue; let first = first;">
<img src="" thumbnail [image]="item?._file"/>
{{ item?.file?.name }}
{{ item?.file?.size }}
</div>
<input type="file" ng2FileSelect [uploader]="uploader" #fileInput [accept]="accept.toString()" [multiple]="multiple"/>
import { Component, OnInit, OnDestroy, Input, Inject, EventEmitter, Output, ElementRef, ViewChild, OnChanges } from '@angular/core';
import { FileUploader, FileItem, FileLikeObject } from 'ng2-file-upload';
@Component({
selector: 'app-upload-field',
templateUrl: './upload-field.component.html'
})
export class UploadFieldComponent implements OnInit {
@ViewChild('fileInput') public fileInput: ElementRef;
@Output('onItemChanged') public onItemChanged = new EventEmitter();
@Input() public url: string = null; // Url api process upload
@Input() public accept: Array<string> = [];
@Input() public maxFileSize: number = 10 * 1024 * 1024; // 10MB
@Input() public maxFile: number = 0; // Default 0 is unlimited
@Input() public multiple: boolean = false; // Default false is single file, true is multiple file
@Input() public errorMessageMaxSize: string = 'Le fichier ne doit pas dépasser 10Mo';
@Input() public errorMessageWrongType: string = 'Ce type de fichier n\'est pas autorisé';
@Input() public errorMessageLimit: string = 'Fichier maximal';
public uploader: FileUploader = new FileUploader({});
constructor() { }
public ngOnInit() {
this.uploader.setOptions(
{
url: this.url,
headers: [{name: 'Accept', value: 'application/json'}],
autoUpload: false,
allowedMimeType: this.accept,
maxFileSize: this.maxFileSize
}
);
this.uploader.onWhenAddingFileFailed = (item, filter, options) => this.onWhenAddingFileFailed(item, filter, options);
this.uploader.onAfterAddingAll = (items) => this.onAfterAddingAll(items);
this.uploader.onAfterAddingFile = (item) => this.onAfterAddingFile(item);
}
/**
* Add file
*/
public addFile(): void {
// Trigger upload file input click event
let event;
if (document.createEvent) {
// Only for IE and Firefox
event = document.createEvent('MouseEvent');
event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
} else {
// For Chrome
event = new MouseEvent('click', {bubbles: true});
}
this.fileInput.nativeElement.dispatchEvent(event);
}
/**
* Check file is image
*
* @param {*} fileType
* @returns {boolean}
*/
public isImage(fileType: any): boolean {
return /^image\/(.*)$/.test(fileType);
}
/**
* Check max file
*
* @returns {boolean}
*/
public isMaxFile(): boolean {
if (this.maxFile === 0) {
return false;
}
return this.uploader.queue.length >= this.maxFile;
}
/**
* Remove file item
*
* @param {FileItem} item
*/
public removeItem(item: FileItem): void {
item.remove();
this.fileInput.nativeElement.value = '';
this.onItemChanged.emit(this.getQueueFiles());
}
/**
* Get queue files
*
* @returns {*}
*/
public getQueueFiles(): Array<any> {
return this.uploader.queue;
}
/**
* Set queue files
*
* @returns {*}
*/
public setQueueFiles(queue: Array<any>): void {
this.uploader.queue = queue;
}
/**
* Get all files in queue
*
* @returns {*}
*/
public getFiles(): Array<any> {
return this.uploader.queue.map(item => item.file);
}
/**
* Add file failed hanlde
*
* @private
* @param {FileLikeObject} item
* @param {*} filter
* @param {*} options
*/
private onWhenAddingFileFailed(item: FileLikeObject, filter: any, options: any) {
switch (filter.name) {
case 'fileSize': {
alert(this.errorMessageMaxSize);
break;
}
case 'mimeType': {
alert(this.errorMessageWrongType);
break;
}
default:
}
}
/**
* Handle choice files
*
* @private
* @param {*} items
*/
private onAfterAddingAll(items: any) {
if (items.length > this.maxFile) {
this.uploader.clearQueue();
this.fileInput.nativeElement.value = '';
alert(this.errorMessageLimit);
this.onItemChanged.emit(this.getQueueFiles());
return;
}
}
/**
* Handle add file
*
* @private
* @param {*} item
*/
private onAfterAddingFile(item: any) {
if (this.checkDuplicateFiles(item)) {
item.remove();
this.onItemChanged.emit(this.getQueueFiles());
}
}
/**
* Check duplicate file
*
* @private
* @param {*} item
* @returns {boolean}
*/
private checkDuplicateFiles(item: any): boolean {
let checkItem: number = 0;
this.uploader.queue.map( itemQueue => {
checkItem += (itemQueue.file.name === item.file.name && itemQueue.file.size === item.file.size) ? 1 : 0;
});
return checkItem > 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment