Reputation: 1083
I'm doing some validation on mat-form-field inputs with Angular Material. The issue is that the mat-error message is not showing up, neither is the outline around the input field. I understand that there is a difference between using reactive forms and the template driven approach with ngModel. In my setup, I am using the latter. I've tried different things like using a template variable, using FormControl etc.
This happens when the mat-error element in inside the mat-form-field element, and when I Inspect the input field, I can see that the mat-error element is not being generated. If I move it outside the mat-form-field element, the error text is shown, but not the outline.
There is no form element around the mat-form-field elements that I can reference. The mat-form-field input fields are inside a mat-dialog.
<mat-dialog-content>
<div class="select">
<mat-form-field floatLabel="always">
<input
type="text"
(blur)="checkType()"
[(ngModel)]="modelType"
matInput
placeholder="Enter type"
[disabled]="false"
required/>
<mat-error *ngIf="typeExists">Type already exists!</mat-error>
</mat-form-field>
</div>
</mat-dialog-content>
component.ts
typeExists: boolean = false;
checkType()
{
//Code that looks in a list to see if the entered value exists in it.
//It just sets a boolean value for typeExists, which is used to show the mat-error message
this.typeExists = existsInList1;
}
I have tried using a template variable like this with no luck:
<mat-dialog-content>
<div class="select">
<mat-form-field floatLabel="always">
<input
type="text"
(blur)="checkType()"
[(ngModel)]="modelType"
#typeInput="ngModel"
matInput
placeholder="Enter type"
[disabled]="false"
required/>
<mat-error *ngIf="typeInput.dirty && typeExists">Type already exists!</mat-error>
</mat-form-field>
</div>
</mat-dialog-content>
Surely, I am not the only one who have had these issues, so I'm hoping someone can chip in.
Upvotes: 1
Views: 187
Reputation: 57939
mat-error only is showed when the "input" is touched and "invalid". So, NOT can showed using a @if
else validating the "formControl"
As you're using Template driven form you need use a directive. See the docs
@Directive({
selector: '[checkIfExist]',
providers: [
{ provide: NG_VALIDATORS, useExisting: CheckIfExistDirective, multi: true },
],
})
export class CheckIfExistDirective implements Validator {
list = input<string[]>([], { alias: 'checkIfExist' });
validate(control: AbstractControl): ValidationErrors | null {
const typeExist = this.list().indexOf(control.value) >= 0;
return typeExist ? { exist: true } : null;
}
}
And use like
<mat-form-field>
<mat-label>Enter your email</mat-label>
<input #emailID="ngModel" [checkIfExist]="your variable"
matInput
placeholder="[email protected]"
[(ngModel)]="email"
required
/>
<mat-error>
@if (emailID.errors?.exist) {
yet in list
} @else{
required
}
</mat-error>
</mat-form-field>
Upvotes: 0
Reputation: 56828
Make sure you have added the below imports.
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
...
...
@Component({
selector: 'input-error-state-matcher-example',
templateUrl: './input-error-state-matcher-example.html',
styleUrl: './input-error-state-matcher-example.css',
standalone: true,
imports: [FormsModule, MatFormFieldModule, MatInputModule], // <- imports!
})
export class InputErrorStateMatcherExample {
...
}
Also ensure you have provideAnimations
set in the bootstrapApplication
level or in the app.module.ts
level.
bootstrapApplication(InputErrorStateMatcherExample, {
providers: [
provideAnimations(),
provideHttpClient(),
importProvidersFrom(MatNativeDateModule)
]
}).catch(err => console.error(err));
Upvotes: 0