I am faced with a problem, I want in my code, to put the focus on a conditioned input
based on data from an observable. In my example I just set a boolean to true
in the ngOnInit()
.
export class InputOverviewExample implements OnInit {
bool: boolean;
@ViewChild("input1", { static: true }) input1: MatInput;
@ViewChild("input2", { static: true }) input2: MatInput;
ngOnInit() {
this.bool = true;
this.input1.nativeElement.focus();
this.input2.nativeElement.focus();
}
}
And I noticed that the focus is not working when a mat-form-field
is conditioned.
<form class="example-form">
<h3>Without *ngIf :</h3>
<mat-form-field appearance="outline" class="example-full-width">
<input matInput #input1 placeholder="Auto focus" value="Test_input1" />
</mat-form-field>
<h3>With *ngIf :</h3>
<mat-form-field appearance="outline" class="example-full-width" *ngIf="bool">
<input matInput #input2 placeholder="Auto focus" value="Test_input2" />
</mat-form-field>
</form>
Someone would have a solution to this problem
Thank you
you need understand ViewChild {static:true} and {static:false} and {read}
So, first define your ViewChild as
@ViewChild("input1", { static: false,read:ElementRef }) input1: ElementRef;
@ViewChild("input2", { static: false,read:ElementRef }) input2: ElementRef;
The static:false
makes that Angular check if is under a *ngIf
The read:ElementRef
makes that your "input1" and "input2" are saw as ElementRef, not as MatInput
The second thing that you need is how Angular works. Angular execute all the actions and refresh the application, so if you write
this.bool = true;
this.input2.nativeElement.focus(); //<--this.input2 is undefined
this.input2 is undefined because Angular has not repaint the application, so you need enclosed by setTimeout -you can think about setTimeout like you say to Angular "hey, don't forget that after refresh the appication, you need make this another instuctions"- or use ChangeDetectorRef.
So
ngOnInit() {
this.bool = true;
setTimeout(()=>{
this.input1.nativeElement.focus();
this.input2.nativeElement.focus();
})
}