My aim is to set focus on an input via the button click method.
I used a template variable, but doing it via component code seems to give the same result.
This works as expected on all devices where I tested (MacBook and some mobile devices) whatever the browser is, i.e. Safari, Chrome, Firefox, however it doesn't work on iOS supporting devices. Nothing happens.
Here is the snippet of the code which is supposed to set the focus to an input on a button click.
Important: It should be run on an iPhone or an iPad.
HTML
<input #input type="text">
<button type="button" (click)="input.focus()">Click to set focus on the input</button>
Here is a small demo for the issue.
You can use the following:
@Component({
selector: 'my-app',
template: `
<div *ngFor="let item of [1,2,3,4]; let i = index">
<button type="button" (click)="display(i)">Click to show and set focus</button>
<input #theInput *ngIf="show === i" type="text" >
</div>
`,
})
export class App {
show = -1;
@ViewChild('theInput')
private theInput;
constructor() {
}
display(i) {
this.show = i;
setTimeout(() => this.theInput.nativeElement.focus(), 0);
}
}
I'm not sure if there is something more elegant than the usage of setTimeout, but since the input is only added to the DOM after the change detection which is triggered by the change of show
, theInput
is undefined (or the previously shown input) at that time.
Demo: http://plnkr.co/edit/A0ZO0hyuR61nUdiSvzFj?p=preview
Edit:
It turns out there is something more elegant: AfterViewChecked:
export class App {
show = -1;
shouldFocus = false;
@ViewChild('theInput')
private theInput;
constructor() {
}
display(i) {
this.show = i;
this.shouldFocus = true;
}
ngAfterViewChecked() {
if (this.shouldFocus) {
this.theInput.nativeElement.focus();
this.shouldFocus = false;
}
}
}
See the updated demo: http://plnkr.co/edit/lXTRDGLKwkAAukEQGQjq?p=preview