90 votes

angular2 déclenche manuellement l'événement click sur un élément particulier

J'essaie de déclencher un événement de clic (ou tout autre événement) sur un élément de manière programmatique, en d'autres termes, je veux connaître les fonctionnalités similaires à celles offertes par la méthode jQuery .trigger() dans angular2.

Existe-t-il une méthode intégrée pour faire cela ? ..... Si ce n'est pas le cas, veuillez me suggérer comment faire.

Considérons le fragment de code suivant

<form [ngFormModel]="imgUploadFrm"
          (ngSubmit)="onSubmit(imgUploadFrm)">
        <br>
        <div class="input-field">
            <input type="file" id="imgFile" (click)="onChange($event)" >
        </div>
        <button id="btnAdd" type="submit" (click)="showImageBrowseDlg()" )>Add Picture</button>
 </form>

Ici, lorsque l'utilisateur clique sur le bouton btnAdd il devrait déclencher l'événement de clic sur imgFile

0 votes

Vous avez seulement besoin imgFile.click() au lieu de showImageBrowseDlg() si vous suivez la réponse ci-dessous par @akshay-khale stackoverflow.com/a/41675017/344029 (après avoir ajouté la variable <input #imgFile )

190voto

Günter Zöchbauer Points 21340

Angular4

Au lieu de

    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);

utilice

    this.fileInput.nativeElement.dispatchEvent(event);

parce que invokeElementMethod ne fera plus partie du moteur de rendu.

Angular2

Utilice ViewChild avec une variable de modèle pour obtenir une référence au fichier d'entrée, puis utiliser la fonction Renderer pour invoquer dispatchEvent pour déclencher l'événement :

import { Component, Renderer, ElementRef, ViewChild } from '@angular/core';
@Component({
  ...
  template: `
...
<input #fileInput type="file" id="imgFile" (click)="onChange($event)" >
...`
})
class MyComponent {
  @ViewChild('fileInput') fileInput:ElementRef;

  constructor(private renderer:Renderer) {}

  showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }
}

Mise à jour

Puisque l'accès direct au DOM n'est plus découragé par l'équipe d'Angular, ce code plus simple peut également être utilisé.

this.fileInput.nativeElement.click()

Voir aussi https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent

0 votes

Vous n'avez pas besoin de déclarer MouseEvent : this.renderer.invokeElementMethod(this.postcardtoggle.nativeElement, 'click', []) ;

10 votes

this.fileInput.nativeElement.click() fonctionne aussi, semble-t-il.

3 votes

@lbrahim : c'est exact. À l'époque, il était fortement suggéré d'éviter d'accéder aux propriétés ou aux méthodes de nativeElement et utiliser Renderer à la place. Je pense que cela a beaucoup changé récemment et que l'accès direct au DOM est bien maintenant, mais cela ne fonctionnera pas avec le rendu côté serveur et les WebWorkers.

27voto

Akshay Khale Points 3658

Je voulais aussi une fonctionnalité similaire où j'ai un Contrôle de l'entrée des fichiers con display:none et un Commande par bouton où je voulais déclencher événement de clic du File Input Control lorsque je clique sur le bouton, voici le code pour le faire

<input type="button" (click)="fileInput.click()" class="btn btn-primary" value="Add From File">
<input type="file" style="display:none;" #fileInput/>

aussi simple que ça et ça fonctionne parfaitement...

1 votes

J'ai utilisé exactement cette méthode pour cliquer sur un bouton après avoir appuyé sur la touche Entrée dans un champ de texte : <input #name type="text" (keyup.enter)="addBtn.click()"> <button #addBtn (click)="add(name.value)" type="button">Add</button>

4voto

Marco C. Points 136

Cela a marché pour moi :

<button #loginButton ...

et à l'intérieur du contrôleur :

@ViewChild('loginButton') loginButton;
...
this.loginButton.getNativeElement().click();

2voto

reneval Points 29

La réponse de Günter Zöchbauer est la bonne. Il suffit d'envisager d'ajouter la ligne suivante :

showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    event.stopPropagation();
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }

Dans mon cas, j'obtiendrais une erreur "caught RangeError : Maximum call stack size exceeded" si non. (J'ai une carte div qui se déclenche au clic et le fichier d'entrée à l'intérieur).

1 votes

Vous pouvez également définir la touche "bubbles" sur false, ce qui empêche l'événement de remonter dans l'arborescence du domaine.

2voto

Rammgarot Points 198

Si vous voulez imiter, cliquez sur l'élément DOM comme ceci :

<a (click)="showLogin($event)">login</a>

et avoir quelque chose comme ça sur la page :

<li ngbDropdown>
    <a ngbDropdownToggle id="login-menu">
        ...
    </a>
 </li>

votre fonction dans component.ts devrait être comme ça :

showLogin(event) {
   event.stopPropagation();
   document.getElementById('login-menu').click();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X