Unfortunately not every solution consistently works with autofocusing matInput at the moment of rendering. Here is what I tried:
- HTML
autofocus
attribute
- JS
input.focus()
cdkFocusInitial
from @angular/cdk
All of the above methods might work but under some conditions they appear to be broken.
What consistently and always works is using a high-level api of the matInput
. Here is a simple directive that uses this approach:
import { Directive, OnInit } from '@angular/core';
import { MatInput } from '@angular/material/input';
@Directive({
selector: '[matInputAutofocus]',
})
export class AutofocusDirective implements OnInit {
constructor(private matInput: MatInput) { }
ngOnInit() {
setTimeout(() => this.matInput.focus());
}
}
The timeout is required to delay focusing the element because matInput does not properly function at the moment of creating yet. Usage:
<mat-form-field>
<input type="text" matInput matInputAutofocus>
</mat-form-field>
Of course, naming the selector matInputAutofocus
is dangerous because material itself can come to this solution one day. Use it on your own risk or just rename with your prefix (recommended).
Focus and meanwhile select the input value
A cherry on the cake is adding the possibility to also preselect the content of the input (this is most of the time more user-friendly), which slightly changes the implementation:
import { Directive, OnInit } from '@angular/core';
import { MatInput } from '@angular/material/input';
@Directive({
selector: '[matInputAutofocus]',
})
export class AutofocusDirective implements OnInit {
@Input()
autofocusSelectValue = false;
constructor(
private matInput: MatInput,
private elRef: ElementRef<HTMLInputElement>,
) { }
ngOnInit(): void {
setTimeout(() => {
this.matInput.focus();
if (this.autofocusSelectValue) {
this.elRef.nativeElement.setSelectionRange(0, this.elRef.nativeElement.value.length);
}
});
}
}
Use it as:
<mat-form-field>
<input type="text" matInput matInputAutofocus [autofocusSelectValue]="true">
</mat-form-field>