Getting current input value in angular template driven form validator

458 Views Asked by At

I have a question regarding an input element type number that I want to validate in a template-driven form:

As the first goal, it should accept only positive integer values. For this, I have created a validator function that gets the input value, evaluates a regex expression, and returns errors if it fails. I wrapped it within a directive and used it with the input element in the template. So far, all is good and it works perfectly.

As the second goal, it should accept a NULL value. For example, since the field is not mandatory, the end user could leave it empty (NULL) and then submit the form. At first, I thought that extending the validator with a condition for when the element is NULL will do the job, and it did. But the problem comes when typing values like -2 or 2.3 or 2.3-... in those cases the validator gets also the input value NULL so I cannot distinguish when the user leaves the input field empty (NULL) or when he's typing an invalid value. I guess the NULL comes from a previous built-in validator running. Is there a way to get access to the actual value of the input field?

this is how the code pretty much looks in the template:

<input
 name="testInputField"
 id="xyz"
 type="number"
 step="1"
 min="0"
 [(ngModel)]="controllerVariable"
 myDirective/>

...and this is how the directive looks like

import { Directive } from '@angular/core';
import { NG_VALIDATORS, AbstractControl, Validator, ValidationErrors, ValidatorFn } from '@angular/forms';
    
export function myValidator(): ValidatorFn {
  const regExp = /^\d+$/;

  return (control: AbstractControl): ValidationErrors | null => {
    return control.value === null
      ? null
      : regExp.test(control.value)
        ? null
        : { myValidator: { valid: false } };
  }
}

@Directive({
  selector: '[myDirective]',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: MyDirective,
    multi: true,
  }],
})
export class MyDirective implements Validator {
  public validate(control: AbstractControl): ValidationErrors | null {
    return myValidator()(control);
  }
};

Any hints or ideas to refactor my solution are highly appreciated. Thanks

0

There are 0 best solutions below