1

I have three input fields, namely

  1. Minimum score
  2. Maximum score
  3. Origin at

So, origin at value must be between minimum score and maximum score.

My form looks like this

this.fb.group({
    min: ['', [Validators.required]],
    max: ['', [Validators.required]],
    origin: ['', [Validators.required, Validators.min(?), Validators.max(?)]] # I need value of min and max input field value here
})

enter image description here

How do I validate origin input field properly?

EDIT:

NOTE - fb is FormBuilder

My entire form

this.scalesForm = this.fb.group({
  scales: this.fb.array([
    this.fb.group({
      type: ['x', [Validators.required]],
      name: ['', [Validators.required]],
      components: this.fb.array([], [Validators.required]),
      min: ['', [Validators.required]],
      max: ['', [Validators.required]],
      origin: ['', [Validators.required]]
    }),
    this.fb.group({
      type: ['y', [Validators.required]],
      name: ['', [Validators.required]],
      components: this.fb.array([], [Validators.required]),
      min: ['', [Validators.required]],
      max: ['', [Validators.required]],
      origin: ['', [Validators.required]]
    })
  ])
});
Vishnudev Krishnadas
  • 10,679
  • 2
  • 23
  • 55

2 Answers2

4

I'll use a custom validator, in your case something like:

export function ValidateOrigin(control: AbstractControl): {[key: string]: boolean} | null {
  if (control.value < this.scalesForm.controls.scales[0].controls.min.value && control.value > this.scalesForm.controls.scales[0].controls.max.value) {
    return { invalidOrigin: true };
  } else {
    return null;
  }
}

// in the form declaration
this.fb.group({
  min: ['', [Validators.required]],
  max: ['', [Validators.required]],
  origin: ['', [Validators.required, ValidateOrigin]]
})
axl-code
  • 2,192
  • 1
  • 14
  • 24
  • Shoudl it be `if (control.value < this.fb.controls.min.value || control.value > this.fb.controls.max.value) {` as that is the condition when error shoudl be reported. Alternatively, you need to use `return null` in `if` block. Currently, it seems implemented other way round. – Wand Maker Feb 12 '20 at 11:05
  • Thanks for the answer @axl-code! Please see updated post. But my form is a form array with two form groups. How can I know from which to select the min and max? (from type: x or type: y) – Vishnudev Krishnadas Feb 12 '20 at 11:41
  • I've updated my answer, check if it works with that structure. But basically I'll create 2 different validation functions (or a parametric generic one for both), one for the x and another one for the y, changing the index of the scales property – axl-code Feb 12 '20 at 11:52
  • you need make the custom form Control over the **full group**, what happens if you change the min after change origin? – Eliseo Feb 12 '20 at 12:24
1

You will have to create a custom validator. First you would need to create your form controls as local variables to make their instances available for your dependent control like this:

const minFormControl = this.fb.control('', [Validators.required]);
const maxFormControl = this.fb.control('', [Validators.required]);

Then you can create your group and add all controls there using a custom validator like this:

this.fb.group({
    min: minFormControl,
    max: maxFormControl,
    origin: this.fb.control('', [Validators.required, CustomValidators.validateMin(minFormControl), CustomValidators.validateMax(maxFormControl)])
})

Then in those you can implement your validation logic.

Blind Despair
  • 3,190
  • 2
  • 20
  • 31
  • Thanks for the answer @Blind Despair. I'll need to create lots of variables/controls just for this because I have this group inside an form array as in the updated post. – Vishnudev Krishnadas Feb 12 '20 at 11:44