How to set autofocus on a matInput element on click event in Angular 6?
You can use cdkFocusInitial from Material.
<mat-form-field>
<input matInput placeholder="username" cdkFocusInitial>
</mat-form-field>
See orginal answer.
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, input.value.length);
}
});
}
}
Use it as:
<mat-form-field>
<input type="text" matInput matInputAutofocus [autofocusSelectValue]="true">
</mat-form-field>
When you use Angular Material, you can use cdkFocusInitial
to tell the library where you want to focus after component is ready. No native approaches are required:
<mat-form-field class="example-full-width">
<mat-label>My Label</mat-label>
<textarea
cdkFocusInitial <---------
cdkTextareaAutosize
matInput>
</textarea>
</mat-form-field>
If you want to set focus to an Input field as soon as the page loads, you can do it simply by applying HTML attribute to that element, such as :
<input type="text" #input1 autofocus>
Else if you want to do this from your component.ts conditionally, use:
import { Component, ElementRef, ViewChild, AfterViewInit} from
'@angular/core';
...
@ViewChild('input1') inputEl:ElementRef;
ngAfterViewInit() {
this.inputEl.nativeElement.focus();
}
Or you can use:
First import the renderer2 from @angular/core and then,
const element = this.renderer.selectRootElement('#input1');
setTimeout(() => element.focus(), 0);
Whatever you seems to be comfortable with your existing code.