user2599052
user2599052

Reputation: 1136

Angular: How to programmatically trigger DOM events, like mouse click?

I want to raise a click MouseEvent programmatically, for example, from an Angular Component to simulate a mouse click. Is this possible and how? I didn't find any existing question on this here.

The DOM element will be some element like a button in a Component template.

Upvotes: 6

Views: 15200

Answers (2)

MoxJet
MoxJet

Reputation: 29

Just wanted to include a quick gotcha here that confused me. Sometimes click will not work the way you think it will when you're using an external component because the (click) output will not be on the first level. For example:

<label class="label">
    <input type="checkbox" class="native-input visually-hidden"
    [disabled]="disabled"
    [checked]="checked"
    (change)="updateValueAndIndeterminate($event)"
    (blur)="setTouched()"
    (click)="$event.stopPropagation()"
    [indeterminate]="indeterminate">
    <span [class.indeterminate]="indeterminate" [class.checked]="checked" class="custom-checkbox">
        <nb-icon *ngIf="indeterminate" icon="minus-bold-outline" pack="nebular-essentials"></nb-icon>
        <nb-icon *ngIf="checked && !indeterminate" icon="checkmark-bold-outline" pack="nebular-essentials"></nb-icon>
    </span>
    <span class="text">
        <ng-content></ng-content>
    </span>
</label>

The click output is on the input within the component template, so you have to call elem.children[0].children[0].click(); to click the checkbox.

Upvotes: 0

Christopher Peisert
Christopher Peisert

Reputation: 24124

In Angular, you would obtain an ElementRef using ViewChild. Then you could either call HTMLElmenent.click() or HTMLElement.dispatchEvent(event).

See Stackblitz Demo

Option 1: Use HTMLElement.click()

import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'


@Component({
  selector: 'my-app',
  template: `
  <h1>Test Angular Programmatic Click Event</h1>

  <div #namedElement (click)="showAlert('Clicked namedElement')">
    Named element
  </div>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit  {
  @ViewChild('namedElement', {static: false}) namedElement: ElementRef;

  public constructor() {}

  ngAfterViewInit() {
    this.namedElement.nativeElement.click();
  }

  public showAlert(msg: string) {
    alert(msg)
  }
}

Option 2: Use HTMLElement.dispatchEvent()

import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'


@Component({
  selector: 'my-app',
  template: `
  <h1>Test Angular Programmatic Click Event</h1>

  <div #namedElement (click)="showAlert('Clicked namedElement')">
    Named element
  </div>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit  {
  @ViewChild('namedElement', {static: false}) namedElement: ElementRef;

  public constructor() {}

  ngAfterViewInit() {
    const event = new MouseEvent('click', {
      view: window,
      bubbles: true,
      cancelable: true
    });

    this.namedElement.nativeElement.dispatchEvent(event);
  }

  public showAlert(msg: string) {
    alert(msg)
  }
}

Upvotes: 7

Related Questions