I tried like this but onDrop
method don't return image files when I drop to it...
onDragStart(event, data: any) {
event.dataTransfer.setData('data', data);
}
onDrop(event, data: any) {
let dataTransfer = event.dataTransfer.getData('data');
event.preventDefault();
}
allowDrop(event) {
event.preventDefault();
}
<div (drop)="onDrop($event, dropData)" (dragover)="allowDrop($event)"></div>
<div (dragstart)="onDragStart($event, dragData)"></div>
Any solution for this?
The event onDrop event fires only when onDragOver has preventDefault()
and stopPropagation()
methods run on event.
HTML
<div
(drop)="onDrop($event)"
(dragover)="onDragOver($event)"
>
Drop target
</div>
DropComponent.ts
export class DropComponent {
onDrop(event) {
event.preventDefault();
}
onDragOver(event) {
event.stopPropagation();
event.preventDefault();
}
}
UPDATE
This is required because by default the browser prevents anything from happening while dropping onto the HTML element. See more at MDN - Defining a valid drop zone
Here is the complete code for drag and drop in Angular 2/4/6 :
drag.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'drag-root',
templateUrl: './drag.component.html',
styleUrls: ['./drag.component.css']
})
export class AppComponent {
allowDrop(ev) {
ev.preventDefault();
}
drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
}
drag.component.html:
<h2>Drag and Drop</h2>
<div id="div1"
(drop)="drop($event)"
(dragover)="allowDrop($event)">
<img
src="https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?auto=compress&cs=tinysrgb&h=350"
draggable="true"
(dragstart)="drag($event)"
id="drag1"
width="88"
height="31">
</div>
<div id="div2"
(drop)="drop($event)"
(dragover)="allowDrop($event)">
</div>
drag.component.css:
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
Snapshots:
You could wrap the onDrop functionality into a reusable directive. Like this:
https://gist.github.com/darrenmothersele/7afda13d858a156ce571510dd78b7624
Apply this directive to an element:
<div (appDropZone)="onDrop($event)"></div>
The event is fired with a JavaScript array of the dropped Files. So, your onDrop
implementation in the component looks something like this:
onDrop(files: FileList) {
console.log({ files });
}
As the others stated you need to call event.preventDefault()
and event.stopPropagation()
on the (dragover)
event to make your container a valid dropzone.
I've written a highly customizable Angular component which implements the correct Drag'n'Drop behavior so I don't need to copy it over and over again which returns a list of the dropped files as an output event.
This can be found here.
After you imported the module you have access to the component:
<ngx-dropzone [multiple]="false" [maxFileSize]="2000"></ngx-dropzone>
You have some options to set and it comes with a decent default styling (screenshots can be found in the GitHub repo). If you want to, you can even take your own div
container with your custom styles and hover effects and put it in the dropzone. Details on this can be found in the API description.
<ngx-dropzone [customContent]="customDropzone" (filesAdded)="onFilesDropped($event)">
<ng-template #customDropzone>
<div class="custom-dropzone">
This is my custom content
</div>
</ng-template>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With