7

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.

2
  • some more downvotes please but with explanation.. Commented Sep 22, 2019 at 16:42
  • 1
    This question has been asked on Stack Overflow with respect to vanilla JavaScript, but not in an Angular context. It is a valid question. Commented Sep 22, 2019 at 17:44

2 Answers 2

8

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)
  }
}

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

4 Comments

Is document object available in component ts file ?
and even if it is provided as a global object, is it a good practice to use it ?
one important point is that I tried it and I don't see angular change detection working with it. Maybe the native element trigger actions are being ignored....
pls let me know if you want to take a look at the snippet ? The event is getting fired and event handler is getting invoked, however inside event handler, I change a property because of which template should have changed but it doesn't.
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.