2

I want to create a button dynamically.I used innerHtml to do this. I can create button.But it's click event not working. Please tell me how to solve this?

Here is my html code

<div  [innerHTML]="answerPanelContent"></div>

Here is my typescript code

 answerPanelContent: any;

   constructor(private sanitizer: DomSanitizer){

   }
ngOnInit() {
 this.answerPanelContent =  this.sanitizer.bypassSecurityTrustHtml(`<button type="button" class="btn                                                    btn-primary float-left"
                                           (click)="removeAnswer()" title="Remove Answer"
                                           aria-label="Close">
                                          Remove</button>`);

  }
    removeAnswer(){
      alert('clicked');
    }

Here is the stackblitz url: https://stackblitz.com/edit/angular-nka4w9

11
  • It is because it will not be angular controlled component, just plaint non sanitized html. Commented Aug 4, 2019 at 10:14
  • If I assign it as a non sanitized,then button not displaying Commented Aug 4, 2019 at 10:19
  • The proper way to do it is to put the HTML in the template, not in the TypeScript code. Use *ngIf="buttonShown" on the button in the template, and in the TS code set this.buttonShown to true to make it appear. Commented Aug 4, 2019 at 10:20
  • @JB Nizet, I can't do that,I created this question for only know how to do this dynamically.Actually what I want is, I have a input field with a button.If I entered something and after clicks that button,I have to show that input value with a button.That button clicks after that field have to close. Here is the full question stackoverflow.com/questions/57345041/… Commented Aug 4, 2019 at 10:32
  • That doesn't change anything. Put the HTML code in the template, and use ngIf to remove or add it to the page based on the state of the component. Or ngFor to generate one row per element of an array of data. Commented Aug 4, 2019 at 10:36

1 Answer 1

11

I strongly recommend not using [innerHTML] for this. It is not meant for this purpose and not the "angular way" at all.

Using *ngFor

This is the most preferable way to solve your issue and "the angular way".

component.ts

export class AppComponent  {
  public buttonsTexts:Array<string> = ['First button'];

  public addButton(index:number):void {
    this.buttonsTexts = [...this.buttonsTexts, `button ${index}`];
  }
}

template.html

<button 
   *ngFor="let buttonText of buttonsTexts; let i = index;"
   (click)="addButton(i)">{{buttonText}}</button>

StackBlitz

Using Renderer2

Use this only if *ngFor is not able to solve your issue because of some requirements that we don't know.

component.ts:

export class AppComponent implements AfterViewInit {
 
  @ViewChild('inserttarget', {static: false})
  public insertTarget:ElementRef; // use this if you want to insert inside a specific element in your template

  constructor(
    private renderer:Renderer2, 
    private el:ElementRef // use this if you want to insert into your template's root
  ) {

  }

  public ngAfterViewInit():void {
    this.addNewButton();
  }


  public addNewButton():void {
    const button = this.renderer.createElement('button');
    const buttonText = this.renderer.createText('Click me');

    this.renderer.appendChild(button, buttonText);
    this.renderer.appendChild(this.insertTarget.nativeElement, button); // use this.el.nativeElement to insert into template root
    this.renderer.listen(button, 'click', () => this.addNewButton());
  }
}

template.ts

<p #inserttarget>
  Some text
</p>

Here a working StackBlitz.

Sign up to request clarification or add additional context in comments.

10 Comments

Why do that this way? Why not just put the HTML in the template, and use ngFor?
Can add that as well - he said in a comment that this is not working for him. Could have been a specific requirement or something that prevents him from using that.
I understand. But no. It's just that he/she doesn't understand the principles of Angular. A basic stackblitz example using ngFor finally made him/her realize that it worked fine, of course. See stackoverflow.com/questions/57345596/…
@pascalpuets,This way is also working.Thanks alot for your help. Can you please check this question stackoverflow.com/questions/57239513/…
@JBNizet Seems I have missed that comment. Of course *ngFor is the most preferrable way to solve this. And one of the most basic things an angular developer should know.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.