Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding button to host element using a angular directive

I'm developing a directive, whose functionality is to add two buttons to the host/parent element. Host/parent element will be a textarea element. I tried to achieve using renderer2 createElement, appendChild methods. Renderer two is creating these buttons and adding to host element like this.

<textarea _ngcontent-c0="" appmarkdown=""><div _ngcontent-c0=""><button _ngcontent-c0="">Hello world</button></div></textarea>

But this way button is not visible. Could anyone help me with this.

code for my directive.

enter code here          import { Directive, Output, EventEmitter, Renderer2, ElementRef, OnInit } from '@angular/core';

      @Directive({
        selector: '[appMarkDown]',
        host:{
          '(keyup)': 'onKey($event.target.value)'
        }
      })
      export class MarkDownDirective implements OnInit {

        constructor(private renderer:Renderer2,private element:ElementRef) { }

        @Output() valuechange:EventEmitter<any> = new EventEmitter();

        private nativeElement : Node;

        ngOnInit() {
          this.nativeElement = this.element.nativeElement;
          const div = this.renderer.createElement('div');
          const button= this.renderer.createElement('button');
          const text = this.renderer.createText('Hello world');
          this.renderer.appendChild(button, text);
          this.renderer.appendChild(div, button);
          this.renderer.appendChild(this.nativeElement, div);
          this.renderer.nextSibling(this.nativeElement)
        }

        onKey(event:KeyboardEvent){
          this.valuechange.emit(event);
        }
      }
like image 744
Nidhin Avatar asked Oct 24 '25 19:10

Nidhin


1 Answers

Since, you are trying to add an button next to an <textarea></textarea>using attribute directive. The correct approach would be to create an component rather than creating directive. Component approach is being used by all the frameworks.

An Attribute directive changes the appearance or behavior of a DOM element.

But here, you are actually changing the structure itself. If it's something you want to do with the help of attribute directive only, then you should apply directive on <div>, where you can insert <textarea> and <button> within it.

If you don't want to change your code, then you should go with

 ngOnInit() {
          this.nativeElement = this.element.nativeElement;
          const div = this.renderer.createElement('div');
          const button= this.renderer.createElement('button');
          const text = this.renderer.createText('Hello world');
          this.renderer.appendChild(button, text);
          this.renderer.appendChild(div, button);
          this.renderer.insertBefore(this.element.nativeElement.parentNode, div, this.element.nativeElement.nextSibling);
        }

Here is link for working solution

like image 144
Nitishkumar Singh Avatar answered Oct 27 '25 12:10

Nitishkumar Singh