Search code examples
javascriptangularhtmldrag-and-dropimage-upload

Drag and drop image with image preview in angular2+


Here, is stackblitz link:- https://stackblitz.com/edit/angular6-ledera?file=app%2Fapp.component.ts

I am trying to drag an image from desktop etc directly and drop on the dropzone div.

1) get preview of the image 2) get the file object.

.html

<div *ngIf="!imageDrop" class="col-12 rmpm dropzone" appDrag>
    <div class="text-wrapper">
        <div class="centered">Drop your file here!</div>
    </div>
</div>
<!--droped image preview-->
<img  *ngIf="imageDrop" [src]="imageDrop" width="100px" height="100px">

dragDrop.directive.ts

@HostBinding("style.background") private background = "#eee";

  constructor() {}

  @HostListener("dragover", ["$event"]) public onDragOver(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    this.background = "#999";
    console.log( '4444:::' + JSON.stringify(evt.target.files));
  }
  @HostListener("dragleave", ["$event"]) public onDragLeave(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    this.background = "#eee";
    console.log( '222:::' + JSON.stringify(evt.target.files));
  }
  @HostListener("drop", ["$event"]) public onDrop(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    let files = evt.dataTransfer.files;
    if (files.length > 0) {
      this.background = "#eee";
      console.log( '1111:::' + JSON.stringify(files));
      console.log( '33333:::' + JSON.stringify(evt.target.files));
    }
  }

Solution

  • Here is a Stackblitz demo for the file drop.

    The directive handles one or multiple files being drop at once.

    It triggers a files event with the file list as parameter, each file is wrapped in a FileHandle interface containing the file and a SafeUrl for the blob created with window.URL.createObjectURL(file).

    export interface FileHandle {
      file: File,
      url: SafeUrl
    }
    
    @HostListener('drop', ['$event']) public onDrop(evt: DragEvent) {
      evt.preventDefault();
      evt.stopPropagation();
      this.background = '#eee';
    
      let files: FileHandle[] = [];
      for (let i = 0; i < evt.dataTransfer.files.length; i++) {
        const file = evt.dataTransfer.files[i];
        const url = this.sanitizer.bypassSecurityTrustUrl(window.URL.createObjectURL(file));
        files.push({ file, url });
      }
      if (files.length > 0) {
        this.files.emit(files);
      }
    }
    

    The consuming component can then display the list of images using the Url created for each file.

    <div *ngFor="let file of files">
      <img *ngIf="file" [src]="file.url" width="100px" height="100px">
    </div>
    

    Hope that helps.