1

I have two mandatory form controls as: minimumCharacters and maximumCharacters. I want to show an error, if the given maximumCharacters is smaller than the given minimumCharacters. Here is how I have defined my form:

this.form.addControl('minimumCharacters', this.formBuilder.control(1, [Validators.required]),{ emitEvent: false });

this.form.addControl('maximumCharacters', this.formBuilder.control('', [maximumCharactersValidator(1)]), { emitEvent: false});

And here is my maximumCharactersValidator:

import { AbstractControl, ValidationErrors, ValidatorFn} from '@angular/forms';


export function maximumCharactersValidator(minValue: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        console.log("control.value: ", control.value);
        let maxValue = control.value;
        if (maxValue > minValue) {
            return { maximumCharactersValid: true}
        }
        else {
            return { maximumCharactersValid: false}
        }
        return null;
    }
}

But this way I don't have access to the control value!

0

2 Answers 2

1

You can work with control.parent to get the parent form group and get the control with name: "minValue"

If the validation is true, you should return { maximumCharactersValid: null } to represent no error. Returning { maximumCharactersValid: true } mean the validation failed.

export function maximumCharactersValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    let minValue = (control.parent as FormGroup)?.get("minimumCharacters")!.value;

    let maxValue = control.value;
    if (maxValue > minValue) {
      return null;
    } else {
      return { maximumCharactersValid: true };
    }
  }
}

When you add the validator, you don't need to provide the argument.

this.form.addControl('maximumCharacters', 
  this.formBuilder.control('', [maximumCharactersValidator()]), { emitEvent: false});

Demo @ StackBlitz

Sign up to request clarification or add additional context in comments.

6 Comments

NOTE: when is valid you should return null NOT {maximumCharactersValid:null} Else the formControl becomes invalid always. (write {{form.controls['maximumCharacters'].valid}} in your .html
Thanks @yong-shun it is working how I want.
Thanks @Eliseo, yes I'm caring of minValue, I just didn't add it to the question to keep it clean.
@Eliseo btw the link you've provided is not correct, can you please provide the right one?
Remember that you need take account also when you change the "minimumCharacter". I love the solution in this SO -And I love quote mySelf :)
|
1

For this kind of situation you generally add FormGroup validator, not FormControl.

export const isInvalidValue = (value: string | undefined | number): boolean => {
  return value === undefined || value === null || value === '';
};

export const minMaxValidator: ValidatorFn = (
  form: AbstractControl
): ValidationErrors | null => {
  const min = form.get('minimumCharacters')!.value;
  const max = form.get('maximumCharacters')!.value;

  if (isInvalidValue(min) || isInvalidValue(max)) {
    return null;
  }

  return Number(min) > Number(max) ? { invalidMinMax: true } : null;
};

form = inject(FormBuilder).group(
  {
    minimumCharacters: [1, Validators.required],
    maximumCharacters: [1, Validators.required],
  },
  { validators: minMaxValidator }
);

StackBlitz example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.