Angular2-focalisation d'une zone de texte sur la charge des composants

je développe un composant dans Angular2 (Beta 8). Le composant a une boîte de texte et un dropdown. Je voudrais mettre le focus dans textbox dès que le component est chargé ou lors d'un changement de dropdown. Comment y parvenir en angular2. Ce qui suit est Html pour le composant.

<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>
52
demandé sur parag 2016-03-04 10:06:42

7 réponses

utilisant l'attribut simple autofocus HTML5 works for' on load 'scenario

 <input autofocus placeholder="enter text" [(ngModel)]="test">

ou

<button autofocus (click)="submit()">Submit</button>

http://www.w3schools.com/TAgs/att_input_autofocus.asp

53
répondu Nikhil Nambiar 2017-02-03 04:03:27

Cette réponse est inspiré par la poste Angulaire 2: Focus sur les nouveaux ajouté l'élément d'entrée

étapes pour mettre l'accent sur L'élément Html dans Angular2

  1. importer des enfants-vue dans votre composant

    import { Input, Output, AfterContentInit, ContentChild,AfterViewInit, ViewChild, ViewChildren } from 'angular2/core';
    
  2. déclarez le nom de la variable du modèle local pour le html pour lequel vous voulez mettre l'accent

  3. mettre en œuvre la fonction ngAfterViewInit() ou d'autres crochets appropriés du cycle de vie
  4. voici le code que j'ai utilisé pour définir la mise au point

    ngAfterViewInit() {vc.first.nativeElement.focus()}
    
  5. ajouter #input attribut à L'élément DOM que vous voulez accéder.

///This is typescript
import {Component, Input, Output, AfterContentInit, ContentChild,
  AfterViewChecked, AfterViewInit, ViewChild,ViewChildren} from 'angular2/core';

export class AppComponent implements AfterViewInit,AfterViewChecked { 
   @ViewChildren('input') vc;
  
   ngAfterViewInit() {            
        this.vc.first.nativeElement.focus();
    }
  
 }
<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input #input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>
51
répondu parag 2017-11-20 00:11:46

la question initiale demandait une façon de se concentrer d'abord, ou de se concentrer plus tard, en réponse à un événement. Il semble que la bonne façon d'aborder ceci est de créer une directive attribut qui peut être définie pour n'importe quel élément d'entrée, puis d'utiliser un événement personnalisé pour déclencher en toute sécurité la méthode focus sur cet élément d'entrée. Pour ce faire, créer d'abord la directive:

import { Directive, Input, EventEmitter, ElementRef, Renderer, Inject } from '@angular/core';

@Directive({
    selector: '[focus]'
})
export class FocusDirective {
    @Input('focus') focusEvent: EventEmitter<boolean>;

    constructor(@Inject(ElementRef) private element: ElementRef, private renderer: Renderer) {
    }

    ngOnInit() {
        this.focusEvent.subscribe(event => {
            this.renderer.invokeElementMethod(this.element.nativeElement, 'focus', []);
        });
    }
}

notez qu'il utilise un renderer.invokeElementMethod sur le nativeElement, qui est web travailleur en sécurité. Notez également que focusEvent est déclaré comme un input.

ajouter ensuite les déclarations suivantes au composant Angular 2 qui a le modèle où vous souhaitez utiliser la nouvelle directive pour mettre l'accent sur un élément d'entrée:

public focusSettingEventEmitter = new EventEmitter<boolean>();

ngAfterViewInit() { // ngOnInit is NOT the right lifecycle event for this.
    this.focusSettingEventEmitter.emit(true);
}
setFocus(): void {
  this.focusSettingEventEmitter.emit(true);
}

n'oubliez pas d'importer EventEmitter au-dessus du composant comme ceci:

import { Component, EventEmitter } from '@angular/core';

et dans le modèle pour ce composant, définissez le nouvel attribut [focus] comme ceci:

<input id="name" type="text" name="name" 
    [(ngModel)]="person.Name" class="form-control"
    [focus]="focusSettingEventEmitter">

enfin, dans votre module, importez et déclarez la nouvelle directive comme ceci:

import { FocusDirective } from './focus.directive';

@NgModule({
    imports: [ BrowserModule, FormsModule ],
    declarations: [AppComponent, AnotherComponent, FocusDirective ],
    bootstrap: [ AppComponent ]
})

pour récapituler: la fonction ngAfterViewInit fera émettre le nouveau EventEmitter, et puisque nous avons assigné cet émetteur à l'attribut [focus] dans l'élément input de notre modèle, et que nous avons déclaré Ce EventEmitter comme input à la nouvelle directive et invoqué la méthode focus dans la fonction arrow que nous avons passé à l'abonnement à cet événement, l'élément input recevra focus après l'initialisation du composant, et chaque fois que setFocus est appelé.

j'ai eu le même besoin dans ma propre application, et cela a fonctionné comme annoncé. Merci beaucoup à ce qui suit: http://blog.thecodecampus.de/angular-2-set-focus-element /

21
répondu Kent Weigel 2016-11-13 00:50:34
<input id="name" type="text" #myInput />
{{ myInput.focus() }}

c'est le meilleur et le plus simple moyen, parce que code" myInput.focus()" s'exécute après l'entrée créé

8
répondu Sergey Gurin 2018-05-17 08:51:06

Voir Angulaire 2: Focus sur les nouveaux ajouté l'élément d'entrée pour savoir comment régler le focus.

Pour "à la charge" utiliser le ngAfterViewInit() cycle de vie de rappel.

4
répondu Günter Zöchbauer 2017-05-23 12:26:38

j'ai eu un problème légèrement différent. J'ai travaillé avec des entrées dans un modal et ça m'a rendu fou. Aucune des solutions proposées n'a fonctionné pour moi.

Jusqu'à ce que je trouve ce numéro: https://github.com/valor-software/ngx-bootstrap/issues/1597

ce bon gars m'a donné l'indication que ngx-bootstrap modal a une configuration de mise au point. Si cette configuration n'est pas définie à false, le modal sera focalisé après l'animation et il n'y a aucun moyen de focaliser quoi que ce soit d'autre.

mise à jour:

pour définir cette configuration, ajouter l'attribut suivant au div modal:

[config]="{focus: false}"

mise à jour 2:

pour forcer la mise au point sur le champ d'entrée j'ai écrit une directive et mis la mise au point dans chaque cycle vérifié par la suite aussi longtemps que le champ d'entrée a le classe ng-intact.

 ngAfterViewChecked() {
    // This dirty hack is needed to force focus on an input element of a modal.
    if (this.el.nativeElement.classList.contains('ng-untouched')) {
        this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }
}
2
répondu FireGnome 2017-07-29 21:43:27

Je n'ai pas eu beaucoup de chance avec beaucoup de ces solutions sur tous les navigateurs. C'est la solution qui a fonctionné pour moi.

pour les changements de routeur:

router.events.subscribe((val) => {
    setTimeout(() => {
        if (this.searchElement) {
            this.searchElement.nativeElement.focus();
        }
    }, 1);
})

puis ngAfterViewInit() pour le scénario onload.

0
répondu rtaft 2018-07-31 17:06:07