Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show mat-error once the textbox is dirty and is on focus?

I want to show the mat-error just after the user has started writing something on an input element. Following is my code:

<mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput type="password" placeholder="Password" required [(ngModel)]='model.password' #password='ngModel' name='Password' [minlength]='requiredLength' [pattern]="passwordPattern">
    <mat-error *ngIf="password.errors?.pattern">
        Password must be 8 characters long, one numeric, one special character....
    </mat-error>
</mat-form-field>

I want to show the error-message once the user has started typing in the input. Currently the error shows up on text-box lost-focus. I have also tried in following way:

<mat-error *ngIf="password.dirty">
    <mat-error *ngIf="password.errors?.pattern">
        Password must be 8 characters long, one numeric, one special character....
    </mat-error>
</mat-error>

But this also produces the same behavior as before. One possible way around would probably using mat-hint. But I don't want to show it as hint as per requirement, I need to show this as error.

By the way, I am using ng-form.

Is it possible to get the specified behavior by using mat-error on ng-form? or I need to customize the css for mat-hint to look it as like the error message?

like image 446
Tasnim Fabiha Avatar asked Jan 20 '19 07:01

Tasnim Fabiha


2 Answers

you can do it in this way -

<mat-form-field appearance="outline">
  <mat-label>Password</mat-label>
  <input matInput 
        type="password"
        placeholder="Password"
        name='Password'
        [ngModel]='model.password'
        (ngModelChange)="onChange($event, password)"
        #password='ngModel'
        [minlength]='requiredLength'
        [pattern]="passwordPattern"
        required>
  <mat-error *ngIf="password.errors?.pattern"">
      Password must be 8 characters long, one numeric, one special character....
  </mat-error>
</mat-form-field>

and in your component.ts add onChange() method -

onChange($event, password){
    this.model.password = $event;
    if(!password.control.touched){
      password.control.markAsTouched();
    }
}
like image 64
Sadid Khan Avatar answered Oct 04 '22 03:10

Sadid Khan


This will apply the new matcher to your entire app:

dirty-error-state.matcher.ts

import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';

export class DirtyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
        return !!(control && control.invalid && (control.dirty || control.touched));
    }
}

app.module.ts

import { DirtyErrorStateMatcher } from 'your-path-here';
import { ErrorStateMatcher } from '@angular/material/core';

@NgModule({
...
  providers: [{
    provide: ErrorStateMatcher,
    useClass: DirtyErrorStateMatcher
  }]
})

Update on 1/2/2021 by Reza Taba:

Added control.touched so if the user leaves the filed without value, the required error kicks in.

like image 26
Christian Avatar answered Oct 04 '22 04:10

Christian