This is actually pretty simple when done using custom directive, main design detail is to use ngModelController. ngModelController provides us with a few interesting possibilities:

  • getting view value ($viewValue property)
  • getting model value ($modelValue property)
  • setting view value ($setViewValue function)
  • access to $parsers and $formatters
  • access to $validators
  • access to field’s ngModel state properties like $touched, $pristine etc.

$validators are useful to do validation of user input and marking field as invalid. But if we want to prevent user from typing some character that we consider invalid we should user $parsers. A function registered as a parser will be invoked every time a model value is to be updated. Registered functions are invoked in order or registration and output from previous function is input to the next one – just like in Chain of Responsibility design pattern. This gives us opportunity to check value that is to be set in the model and modify it. Let’s take a look at an example:

Directive comValidate requires ngModelController. Once ngModelController is injected to directive’s link function we can register a parser function which will do required tests of value provided by the user. In above directive a test is done to check if value is a number. If it is then newValue is passed on to next $parser function. If not, then:

  • view value is updated and rendered – it is important to call $render otherwise user would see invalid character from time to time (although it would not be present in the model)
  • current model value is passed to the next $parser function instead of newValue. This is also important – as if we return e.g. undefined input will be cleared.

Example code on plunkr.

Have a nice day !