0

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

2
  • Thanks for the question, I learnt something new today! stackoverflow.com/questions/41756020/… This seems like a really dumb side effect of applying type="number" to an <input> field, I'm actually shocked this is the way it works. One option is clearly to not use type="number" and instead use type="text". Assuming this is not a valid option, I would consider passing in the value from the <input> DOM element itself, e.g. using @ViewChild() and viewChildVariable.nativeElement.target.value. Commented Oct 21, 2022 at 17:50
  • 1
    @nate-kumar even with your approach, value is NULL in the nativeElement. After having a look at Mozilla I come to the conclusion that if I want to accept NULL as a valid value, <input> type "number" won't work. I believe choosing the type "text" will do the job Commented Oct 24, 2022 at 8:35

0

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.