web-dev-qa-db-fra.com

Angular 5 set focus sur l'élément input

Je travaille avec une application frontale avec Angular 5 et il me faut un champ de recherche masqué, mais si vous cliquez sur un bouton, le champ de recherche s’affiche et est activé.

J'ai essayé quelques façons trouvées dans stackoverflow avec directive ou presque, mais sans fortune.

Voici l exemple de code :

@Component({
   selector: 'my-app',
   template: `
    <div>
    <h2>Hello</h2>
    </div>
    <button (click) ="showSearch()">Show Search</button>
    <p></p>
    <form>
      <div >
        <input *ngIf="show" #search type="text"  />            
      </div>
    </form>
    `,
  })
  export class App implements AfterViewInit {
  @ViewChild('search') searchElement: ElementRef;

  show: false;
  name:string;
  constructor() {    
  }


  showSearch(){
    this.show = !this.show;    
    this.searchElement.nativeElement.focus();
    alert("focus");
  }

  ngAfterViewInit() {
    this.firstNameElement.nativeElement.focus();
  }

La zone de recherche n'est pas définie pour la mise au point .. Comment puis-je le faire? Merci.

13
Bob

Modifier la méthode de recherche d'exposition comme ceci

showSearch(){
  this.show = !this.show;  
  setTimeout(()=>{ // this will make the execution after the above boolean has changed
    this.searchElement.nativeElement.focus();
  },0);  
}
17
Arvind Muthuraman

Vous devriez utiliser html autofocus pour cela:

<input *ngIf="show" #search type="text" autofocus /> 

Remarque: si votre composant est conservé et réutilisé, il effectuera une mise au point automatique uniquement à la première création du fragment. Cela peut être surmonté en ayant un auditeur dom global qui vérifie la présence d'un attribut autofocus dans un fragment dom lorsqu'il est attaché, puis en le réappliquant ou en effectuant la focalisation via javascript.

7
N-ate

Cette directive met instantanément en évidence et sélectionne le texte de l'élément dès son affichage. Cela peut nécessiter un setTimeout dans certains cas, cela n’a pas été beaucoup testé. 

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[appPrefixFocusAndSelect]',
})
export class FocusOnShowDirective implements OnInit {

  constructor(private el: ElementRef) {
    if (!el.nativeElement['focus']) {
      throw new Error('Element does not accept focus.');
    }
  }

  ngOnInit(): void {
    const input: HTMLInputElement = this.el.nativeElement as HTMLInputElement;
    input.focus();
    input.select();
  }
}

Et dans le HTML:

 <mat-form-field>
     <input matInput type="text" appPrefixFocusAndSelect [value]="'etc'">
 </mat-form-field>
3
ggranum

Pour effectuer l'exécution après la modification du booléen et éviter l'utilisation du délai d'attente, vous pouvez effectuer:

import { ChangeDetectorRef } from '@angular/core';

constructor(private cd: ChangeDetectorRef) {}

showSearch(){
  this.show = !this.show;  
  this.cd.detectChanges();
  this.searchElement.nativeElement.focus();
}
1
Marcin Restel