These are my instructions for implementing drag and drop functionality.
Initially, I was applying my logic on click events to add a component to my div element. However, now I need to modify it to support drag and drop operations.
import {
Directive, Output, EventEmitter, ElementRef, Input, Renderer, ViewContainerRef, ViewChild, ComponentResolver,
ComponentRef
} from '@angular/core';
import {Div444} from "../gridmanager/div4-4-4.component";
declare var jQuery:JQueryStatic;
@Directive({
selector: '[dnd_drag_grid]',
host: {
'(dragstart)': 'onDragStart($event)',
'(dragend)': 'onDragEnd($event)',
'(drag)': 'onDrag($event)',
}
})
export class dnd_drag_grid {
elementDrag:HTMLElement;
@Input("drag") drag;
set draggable(value:boolean) {
this.drag = !!value;
}
elem:HTMLElement;
constructor(private componentRef:ComponentRef, private resolver:ComponentResolver,
private el:ElementRef, private renderer:Renderer) {
this.renderer.setElementAttribute(this.el.nativeElement, 'draggable', 'true');
this.renderer.setElementStyle(this.el.nativeElement, 'cursor', 'move');
}
onDrag(event:MouseEvent) {
console.log(" -----onDrag---- " + this.drag);
this.renderer.setElementStyle(this.el.nativeElement, 'border-style', 'dotted');
}
onDragEnd(event:Event) {
console.log(" -----DragEnd---- " + this.drag);
this.renderer.setElementStyle(this.el.nativeElement, 'border', 'none');
}
onDragStart(event:DragEvent) {
console.log(" ----DragStart----- " + this.drag);
this.elementDrag = this.el.nativeElement;
}
}
@Directive({
selector: '[dnd_drop_grid]',
host: {
'(dragover)': 'onAllowDrop($event)',
'(drop)': 'onDrop($event)',
'(dragleave)': 'ondragleave($event)',
'(dragenter)': 'onDragEnter($event)'
}
})
export class dnd_drop_grid {
elementDrop:HTMLElement;
@Input("drop") drop;
@Input("target") target;
set droppable(value:boolean) {
this.drop = !!value;
}
set setTarget(value:string) {
this.target = value;
}
elem:HTMLElement;
@ViewChild('', {read: ViewContainerRef}) component_target;
constructor(private componentRef:ComponentRef, private resolver:ComponentResolver,
private el:ElementRef, private renderer:Renderer) {
console.log("target "+ this.target);
}
onAllowDrop(event:DragEvent) {
this.component_target = this.target;
console.log("target "+ this.target);
console.log("on allow drop ");
event.preventDefault();
this.renderer.setElementStyle(this.el.nativeElement, 'borderStyle', 'dotted');
this.renderer.setElementStyle(this.el.nativeElement, 'borderColor', 'red');
}
ondragleave(event:DragEvent) {
this.renderer.setElementStyle(this.el.nativeElement, 'borderStyle', 'bridge');
this.renderer.setElementStyle(this.el.nativeElement, 'borderColor', 'white');
console.log("target "+ this.target);
}
onDragEnter(event:Event) {
console.log("target "+ this.target);
}
onDrop(event:DragEvent) {
console.log("target "+ this.target);
this.elementDrop = this.el.nativeElement;
event.preventDefault();
this.resolver.resolveComponent(Div444).then((factory) => {
this.componentRef = this.component_target.createComponent(factory);
});
this.renderer.setElementStyle(this.el.nativeElement, 'borderStyle', 'bridge');
this.renderer.setElementStyle(this.el.nativeElement, 'borderColor', 'white');
console.log("Item has been dropped!");
}
}
I have added the following code snippet in my HTML template:
<li dnd_drag_grid drag="true">Div 4-4-4</li>
<div dnd_drop_grid target="val" drop="true" class="page" id="content" size="A4" layout="portrait">
<div #val hidden></div>
</div>
The error that I am encountering is:
Unhandled Promise rejection: _this.component_target.createComponent is not a function ; Zone: angular ; Task: Promise.then ; Value: TypeError: _this.component_target.createComponent is not a function(…)