2
votes

Since using reactive forms with ngModel is deprecated in Angular 6 and my project depends heavily on using ngModel, I decided to replace my reactive forms with template driven forms.

Before I do that, I want to make sure that all the things possible with reactive forms are possible with template driven forms as well.

One of the things that I need, but couldn't find any information on, is using custom validator function IN THE CONTROLLER with template driven forms. All of the tutorials that I've checked are creating separate directives for the custom validator or doing somthing similar to that.

I however really need to be able to access the data in the controller in the validator function, because the validity of a field depends on other data and other properties in the view. Also for the particular use case I find this making more sense than creating a separate file for the validator.

With the reactive forms I could do something like this:

this.thisForm = new FormGroup({
      smallerValue: new FormControl('', [
        this.validateSuccessShortName.bind(this) //the validator function
      ]),
      biggerNumber:new FormControl('', [
        Validators.required
      ])
    });
  }
  validateSuccessShortName(control: AbstractControl) {
      if (parseInt(control.value,10) > parseInt(this.biggerNumber, 10)) {
        return {value: control.value};
      }
      return null;
    }

However I can't find a way to do this for template driven forms.

How can I do something like this in template-driven forms?

The reactive forms example in stackblitz:

https://stackblitz.com/edit/ionic-tqp9o1?embed=1&file=pages/home/home.ts

2

2 Answers

1
votes

you can do it in 2 ways.

1) you could use a validate function on button click event and throw the error when the condition is not passed.

<button type="button" (click)="validateSuccessShortName(smallerValue, biggerNumber)">

and validate in your TS file.

2) use (ngModelChange) in either of the respective fields. if you wanna validate in smallerValue field use it there Or in the biggerNumber Value. i.e:

<input type="text" [(ngmodel)]="smallerValue" (ngModelChange)="validateSuccessShortName()"> 

pass your values and validate them as you type in.

I'd prefer the 2nd one.

Hope this helps.

0
votes

you can use angular custom validation library https://www.npmjs.com/package/ngx-validator

for example you have class

class MyClass {

 @ValueRange({min: 1, max:10, error: 'value should be from 1 to 10'})
 id: number;

}

note @ValueRange({min: 1, max:10, error: 'value should be from 1 to 10'}) here. It is the kind of data annotations used in aspnet mvc models. this library does something like this. Use this in your template driven form

<ngx-input-for 
   [model]="model" > 
   [(ngModel)]="model.id"
   name="id"
</ngx-input-for>   

then id will do all custom validations for you.

totally, there are following custom validation functions:

DataType, CreditCard, Contains, Compare, Name, Required, RequiredIf, Pattern, MinValue, MaxValue, NotContains, StringLength, Email, Custom, NoForm, ReadOnly, ValueRange