In today’s article, we will see how to drag and drop images from your computer to an Angular 8 web application using our custom directive.
Why do we need this?
In today’s world, almost all of the web applications have to deal with images on some level. Usually, the application provides a way to upload images but for better user experience, selecting multiple images at once and performing a drag and drop operation to your web application is a very common feature these days.
Let’s get started.
Open cmd at the location where you want to create your Angular project and enter the following command
ng new ImageDragDrop
Once the creation of the project is done, open it up with your favorite editor (VS Code in my case)
Now we will create our new component in which we will implement the drag and drop feature.
For that run this command in the terminal:
ng g c image-upload
After the execution of this command, you will see a folder generated with image-upload name
Now we will go to app.component.html, delete everything on that file and just add the selector of your newly-generated component.
<app-image-upload></app-image-upload>
Now let’s run our project. In the root folder of our project let’s run the command:
ng serve
When it runs completely, go to our browser and open the following URL:
http://localhost:4200
Now let us create a directive. We will run this following command in the terminal:
ng g d ImageDrag
After the execution of the following command, you will see these two files:
Now we will add an interface that will look something like this:
Now we will modify our ImageDrag directive according to our functionality:
With the help of @HostListner we will add three events to our directive
We will also have an output property that will emit the array of dropped files.
Our directive will look something like this,
- import {
- Directive,
- HostListener,
- EventEmitter,
- Output,
- HostBinding,
- } from '@angular/core';
- import {
- FileHandle
- } from './file-handle';
- import {
- DomSanitizer
- } from '@angular/platform-browser';
- @Directive({
- selector: '[appImageDrag]',
- })
- export class ImageDragDirective {
- @Output('files') files: EventEmitter < FileHandle[] > = new EventEmitter();
- @HostBinding('style.background') public background = '#eee';
- constructor(private sanitizer: DomSanitizer) {}
- @HostListener('dragover', ['$event']) public onDragOver(evt: DragEvent) {
- evt.preventDefault();
- evt.stopPropagation();
- this.background = '#999';
- }
- @HostListener('dragleave', ['$event']) public onDragLeave(evt: DragEvent) {
- evt.preventDefault();
- evt.stopPropagation();
- this.background = '#eee';
- }
- @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);
- }
- }
- }
Here in drop event, we are just getting the files from DragEvent, and in order to show their preview, we are using DomSantizer to obtain their URL to show in img tags.
Now in order to use this, we will go back to our ImageUpload component, open its HTML file and place this piece of code there,
- <div
- style="width: 500px; height: 250px; text-align: center;"
- appImageDrag
- (files)="filesDropped($event)"
- >
- <span style="font-size: 25px;">Drop your files here</span>
- </div>
- <div style="margin-top: 20px; width: 500px; height: 400px;">
- <div *ngFor="let file of uploadedFiles">
- <img [src]="file.url" style="width: 100px; height: 100px;" />
- </div>
- </div>
Now we will go to its component file and modify it accordingly,
- import {
- Component,
- OnInit
- } from '@angular/core';
- import {
- FileHandle
- } from '../file-handle';
- @Component({
- selector: 'app-image-upload',
- templateUrl: './image-upload.component.html',
- styleUrls: ['./image-upload.component.css'],
- })
- export class ImageUploadComponent implements OnInit {
- uploadedFiles: FileHandle[];
- constructor() {}
- ngOnInit(): void {}
- filesDropped(files: FileHandle[]) {
- this.uploadedFiles = files;
- }
- }
Now let’s run our application
Summary
In today’s article, we have seen how we can drag and drop images from our local computer to our angular 8 web application using our own custom directive.