cucuru
cucuru

Reputation: 3708

validate a form using other form values

I have a reactive form and I want to create a custom validator, based on the inputs should be incremental.

Those are my html and validator

 <form [formGroup]="form">
     <input type="number" matInput formControlName="value0" placeholder="value0" />
     <input type="number" matInput formControlName="value1" placeholder="value1" />
     <input type="number" matInput formControlName="value2" placeholder="value2" />
 </form>

export function valuesValidator(previous: number): ValidatorFn {
  return (control: AbstractControl): { [key: string]: boolean } | null => {
  if (previous > control.value) {
    return { 'incrementalValue': true };
  }
  return null;
 };
}

the problem is when I try to use the validator when starting the form, I'm trying to get at same time than create and it crashes:

private initForm() {
  this.form = this.formBuilder.group({
    value0: [this.value0, Validators.required],
    value1: [this.value2, valuesValidator(this.form.value.value0)],
    value2: [this.value3, valuesValidator(this.form.value.value1)],

});

}

How can I use my validator?

Upvotes: 1

Views: 52

Answers (1)

MoxxiManagarm
MoxxiManagarm

Reputation: 9134

I'm trying to get at same time than create and it crashes:

What does that mean?

However, what you are looking for is a Cross-Form Validator. You can read about examples here:

A crossform validator is a validator which does not receive a FormControl, but a FormGroup. You then extract your required values from that FormGroup and use them together.

When I understand you right, then you want to validate, that value1 < value2 < value 3. That could look like this:

this.form = this.formBuilder.group({
    value0: [this.value0, Validators.mandatory],
    value1: [this.value1, Validators.mandatory],
    value2: [this.value2, Validators.mandatory],
}, { validator: IncrementalValuesValidator });

const IncrementalValuesValidator: ValidatorFn = (fg: FormGroup) => {
  const v1= fg.get('value0').value;
  const v2= fg.get('value1').value;
  const v3= fg.get('value2').value;

  return v1 < v2 && v1 < v3 && v2 < v3
    ? null
    : { 'incrementalValue': true };
};

Upvotes: 2

Related Questions