Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material validation without reactive forms

I am struggling to get the Angular Material forms validation work with Angular Template forms. All examples are working with reactive forms only.

I am generating template Angular Material template forms in the following form:

<mat-form-field *ngSwitchCase="'text'" class="entity-form-field" appearance="outline">
  <input matInput [placeholder]="field.title" [value]="getValue(field)" 
    (change)="setValue(field, $event)" [required]="field.req" [id]="field.id">
  <mat-error *ngIf="fieldInvalid(field)">{{getErrorMessage(field)}}</mat-error>
</mat-form-field>

Both fieldInvalid and getErrorMessage are working fine, so the field error message should be visible. If I change it to a different tag then it will be visible:

<p *ngIf="fieldInvalid(field)">{{getErrorMessage(field)}}</p>

I understand that the Reative Forms have to change the state of the input to make change it's style to make it visible.

Is there a way to do the same with simple Template Forms? I could probably also apply the Angular Material error styles, but I can't find the documentation.

like image 737
hoonzis Avatar asked Jun 29 '18 10:06

hoonzis


People also ask

How do you set a validator dynamically?

We can add Validators dynamically using the SetValidators or SetAsyncValidators. This method is available to FormControl, FormGroup & FormArray. There are many use cases where it is required to add/remove validators dynamically to a FormControl or FormGroup.

What is form dirty in angular?

When the user changes the value in the watched field, the control is marked as "dirty" When the user blurs the form control element, the control is marked as "touched"

How do you validate a form in ngModel?

The ngModel property is used to bind the form control to the model. For validating the user name availability we will use the appValidateUserName directive on the username field. Similarly, we will use the appPasswordPattern directive on the password field to validate the password pattern.

How to build and validate a form in angular?

To build and validate the form in angular, we will use the Reactive form API. It offers the ReactiveFormsModule that is really essential for managing the forms. As we know, there are 2 types of Form types offered by Angular. In this tutorial, we’ll be using Reactive Forms to create and validate forms.

How to use reactive forms in angular?

To use Reactive forms in Angular app, we need to import ReactiveFormsModule in app.module.ts file. To manage the data in Angular, we need to understand some core APIs of Reactive forms. FormGroup: FormGroup API holds the values, properties, and validation state of a group in Reactive forms.

How do you validate a form in reactive form?

Reactive form validation link. In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class. Angular then calls these functions whenever the value of the control changes.

What are the different types of forms in angular?

As we know, there are 2 types of Form types offered by Angular. In this tutorial, we’ll be using Reactive Forms to create and validate forms. Our focus will be on common Reactive Forms API: FormControl, FormGroup, FormaArray, and FormBuilder. Reactive Forms is an easy to use service, and Reactive forms are used to handle more complex data.


2 Answers

Solved this after reading Angular doc (https://angular.io/guide/forms):

<mat-form-field>
<input matInput [(ngModel)]="scenario.name" name="scenarioName" 
#scenarioName="ngModel"
placeholder="Scenario name" class="form-control"
required minlength="3">
<mat-error [hidden]="scenarioName.valid">Scenario name should have at least 3 symbols</mat-error>
</mat-form-field>

So the key was #scenarioName="ngModel" bit which then Angular uses to assign valid/invalid properties that you can then use for mat-error visisbility.

like image 142
IlyaP Avatar answered Oct 19 '22 23:10

IlyaP


This is not a pure solution, but simple and feasable workaround. Mat-hint can easily be styled as error and conditionally shown only in error state:

<mat-form-field>
  <mat-label>Label</mat-label>
  <input matInput ...>
  <mat-hint class="error-hint" *ngIf="fieldInvalid(field)">{{getErrorMessage(field)}}</mat-hint>
</mat-form-field>

And the error-hint class:

.error-hint {
  color: red;
}
like image 22
hoonzis Avatar answered Oct 19 '22 23:10

hoonzis