Similar to Google Login page, I want to have autofocus on input element after on click event. I have tried @ViewChild('id') and document.getElementId('id'). Both of it doesn't work. It's always null or undefined. How can I achieve this?
<mat-form-field class="example-full-width col-sm-4">
<input autofocus id="login-username" matInput
formControlName="userName" minlength="5" maxlength="20"
name="userName" placeholder="Username" required #input>
</mat-form-field>
<div class="col-sm-12">
<button (click)="changeView()" type="button" mat-raised-
button color="primary">Next</button>
</div>
<mat-form-field class="example-full-width col-sm-4"
#passwordInput>
<input autofocus type="password" matInput
placeholder="Password" minlength="5" maxlength="20"
formControlName="userPassword" #passwordInput>
</mat-form-field>
MatFormFieldControl. An interface which allows a control to work inside of a MatFormField .
To change the mat form field border color in Angular, you have to target the . mat-form-field-outline class . This class is responsible for the 4 sides of borders around the mat form field element. So, to change the mat form field border color, you have to simply override the existing border color with the new one.
Unfortunately not every solution consistently works with autofocusing matInput at the moment of rendering. Here is what I tried:
autofocus
attributeinput.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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With