I am developing the drag and drop application in Angular 6 and on drop operation, I am creating the new HTML element (elements like 'DIV', 'textarea' etc.), dynamically and assign styles, attributes, default x and y coordinates to it by using ElementRef and Renderer2 features of application and adding the newly created HTML element to parent element on which drop operation is being performed.
I also have an angular directive created which attaches draggable behavior to the newly created HTML element so user can move it anywhere on the parent element. The partial code for directive is given below:
@Directive({
selector: '[appMovable]'
})
export class MovableDirective {
@HostBinding('style.transform') get transform(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle(
`translateX(${this.position.x}px) translateY(${this.position.y}px)`);
}
private position = {x: 100, y: 0};
constructor(private sanitizer: DomSanitizer) {
}
@HostListener('dragStart') onDragStart() {
console.log('drag start');
// Code to calculate the start position of the control being dragged....
}
@HostListener('dragMove') onDragMove() {
console.log('drag move');
// Code to calculate the current position of the control while it is being dragged....
}
@HostListener('dragEnd') onDragEnd() {
console.log('drag end');
// Code to calculate the end position of the control being dragged and the the position of the control properly.....
}
}
While I am able to assign the styles, attributes and default x and y coordinates to the newly created element but I am not able to bind the 'appMovable' directive to newly created HTML element. The code to create the HTML element and assigning different attributes to it is as below:
@Directive({
selector: '[appDroppable]'
})
export class DroppableDirective {
constructor(private elementRef: ElementRef, private renderer: Renderer2) {
}
@HostListener('dragover', ['$event'])
public onDragOver(evt) {
evt.preventDefault();
evt.stopPropagation();
}
@HostListener('dragleave', ['$event'])
public onDragLeave(evt) {
evt.preventDefault();
evt.stopPropagation();
}
@HostListener('drop', ['$event'])
public onDrop(evt) {
evt.preventDefault();
evt.stopPropagation();
// Since text element is being dragged so create new textarea html control
const textareaElement = this.renderer.createElement('textarea');
this.renderer.setAttribute(textareaElement, 'placeholder', 'click to add content...');
this.renderer.setAttribute(textareaElement, 'class', 'proInput editing');
this.renderer.setAttribute(textareaElement, 'draggable', 'true');
//Assign the appMovable directive to element
this.renderer.setAttribute(textareaElement, 'appMovable', '');
// this.renderer.appendChild(newDivElement, textareaElement);
this.renderer.appendChild(this.elementRef.nativeElement, textareaElement);
}
}
When I inspect the newly created HTML element in the browser debugger tool, I can see the appMovable directive getting assigned to the HTML element but element does not behave as per the directive assigned to it.
Is there anything else needs to be done or there is any alternate option to get directive work properly with dynamically created HTML elements?