ionic DIY上傳組件

效果圖:

file-input.component.ts

import {
    Component,
    ElementRef,
    EventEmitter,
    HostListener,
    Input,
    Output,
} from '@angular/core';

@Component({
    selector: 'app-file-input',
    templateUrl: './file-input.html',
    styleUrls: ['./file-input.scss']
})
export class FileInputComponent {
    public isDrag: boolean = false;
    public progress = 30;
    public progressDisplay = false;
    public filenameDisplay = false;
    public fileName = '';
    public filePath: any;
    @Output() fileRead: EventEmitter<any> = new EventEmitter();
    @Output() fileCancel: EventEmitter<any> = new EventEmitter();
    @Output() fileUpload: EventEmitter<any> = new EventEmitter();
    @Input() messages: string[] = [];
    @Input() inputShowFile: string = '0';
    constructor(public el: ElementRef) {}

    @HostListener('drop', ['$event'])
    onDrop(ev: any) {
        ev.preventDefault();
        this.progressDisplay = true;
        let files = [];
        [].forEach.call(ev.dataTransfer.files, function(file) {
          files.push(file);
        },false);
        console.log(files);
        const file: any = ev.dataTransfer.files[0];
        this.messages.splice(0);
        this.fileRead.emit(ev);
        const temp = setInterval(() => {
            this.clearPross(temp, file);
        }, 100);
    }

    @HostListener('dragleave', ['$event'])
    onDragLeave(ev: Event) {
        ev.preventDefault();
        this.isDrag = false;
    }

    @HostListener('dragover', ['$event'])
    onDragOver(ev: Event) {
        ev.preventDefault();
        this.isDrag = true;
    }

    @HostListener('dragenter', ['$event'])
    onDragEnter(ev: Event) {
        ev.preventDefault();
        this.isDrag = true;
    }

    public cancel(): void {
        this.filenameDisplay = false;
        this.progress = 30;
        this.fileName = '';
        this.messages.splice(0);
        this.fileCancel.emit();
    }

    private clearPross(pro: any, file: any): void {
        this.progress = this.progress + 30;
        if (this.progress > 100) {
            this.progress = 100;
            clearInterval(pro);
            setTimeout(() => {
                this.progressDisplay = false;
                this.fileName = file.name;
                this.filenameDisplay = true;
                this.isDrag = false;
                this.progress = 0;
            }, 100);
        }
    }

    public openFile(): void {
        this.el.nativeElement.querySelector('#file-input-read').click();
        this.progress = 0;
        this.filePath = undefined;
    }

    public fileChoose(event?: any): void {
        if (event) {
            event.preventDefault();
            this.progressDisplay = true;
            const file: any = this.getDocInfo(event);
            this.messages.splice(0);
            setTimeout(() => {
                this.fileRead.emit(event);
            }, 500);
            const temp = setInterval(() => {
                this.clearPross(temp, file);
            }, 100);
        }
        this.filePath = undefined;
    }

    public upload(): void {
        this.fileUpload.emit();
    }

    public getDocInfo(event: any): any {
        const fileToUpload = event.dataTransfer ? event.dataTransfer.files[0] : event.target.files[0];
        const fileName = fileToUpload.name;
        const fileSize = fileToUpload.size;
        const lastModifiedDate = fileToUpload.lastModifiedDate;
        const date = new Date(lastModifiedDate);
        const modifiedDate = date.getFullYear().toString() + '-' + this.dateTemp(date.getMonth()) + '-' + this.dateTemp(date.getDate()) + ' ' + this.dateTemp(date.getHours()) + ':' + this.dateTemp(date.getMinutes()) + ':' + this.dateTemp(date.getSeconds());
        const file = { name: fileName, size: fileSize, modifiedDate: modifiedDate };
        return file;
    }

    private dateTemp(num: number): any {
        return (Array(2).join('0') + num).slice(-2).toString();
    }
}

file-input.html

<ion-list class="file-input-list">
    <ion-item lines="none" class="file-input" [ngClass]="{'file-input-drag':isDrag, 'file-input-drag-error':messages.length !== 0}">
      <ion-chip (click)="openFile()">
        <ion-icon name="search"></ion-icon>
        <ion-label>文件選擇或者拖動文件到此</ion-label>
      </ion-chip>
      <input type="file" id='file-input-read' [(ngModel)]="filePath" (change)="fileChoose($event)" style="display: none;">
      <ion-button [disabled]="fileName == ''" size="default" (click)="upload()">上傳</ion-button>
    </ion-item>
    <ion-progress-bar  [value]="progress" max='100' *ngIf="messages.length === 0 && progressDisplay"></ion-progress-bar>
    <ion-chip (click)="openFile()" [color]="messages.length !== 0?'warning':'primary'" *ngIf="filenameDisplay && inputShowFile == '0'">
      {{fileName}}
      <ion-icon name="close" (click)="cancel()"></ion-icon>
    </ion-chip>
    <ng-container *ngIf="messages.length !== 0">
      <ng-container *ngFor="let message of messages; let i = index">
        <ion-item lines="none" color="warning" class="file-input-error">{{message}}</ion-item>
      </ng-container>
    </ng-container>
  </ion-list>

file-input.scss

.file-input {
  border: 1px solid #bcc4ca;
  padding: 7px 0px;
}
.file-input-drag {
  border: 1px dashed #054666;
  padding: 7px 0px;
}
.file-input-drag-error {
  border: 1px solid red;
  padding: 7px 0px;
}
.file-input-error {
  --min-height: 24px;
}
.file-input-list {
  display: inline-grid;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章