1

I have a form that contain date inputs and select elements,
I tried to use ngChange but I found it not very useful when handling dates errors.
So I'm trying to set a watcher in a directive for every input.$error in order to display error message to the user.

my directive:

module.directive('validator', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) {
      scope.input = ctrl;
      scope.$watch('input.$error', function() {
        console.log(scope.input);
      }, true);
    }
  }
}]);

The problem with the directive is that the scope.$watch fires only when an error object of dates is changing, and the scope.input of every input becomes similar to the ctrl of the changed date input.

JSFiddle

0

3 Answers 3

1

Update your directive to watch if the input is invalid

 module.directive('validator', [function() {
    return {
    restrict: 'A',
    require: '^form',
    link: function(scope, elem, attr, form) {

      var inputName = attr.name;
      console.log(inputName, form[inputName].$error)
      function watcherForRequired(){
       return form[inputName].$error.required;
      }
      function watcherForMin(){
       return form[inputName].$error.min;
      }
      scope.$watch(watcherForRequired, function(required) {
        console.log("required", required);
      })
      scope.$watch(watcherForMin, function(min) {
        console.log("min error", min);
      })
    }
  }

also update ng-min to min="{{loan.loaned}}"

here is JSFiddle

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

5 Comments

I want to set the watcher for the $error because I want to change the error message dynamically, e.g. when the date error is changing from required to min
actually error object stores both required and min keys. when min error occurs $error changes to myForm.input.$error = {"min":true}. So you need to watch $error, as you did. But ng-min is only applied when the input type is number. So in date type it doesnt work
return form[inputName].$error soukd work in your case if tyoe is number
The ngMin can be either string or date inside input[date] docs
It's working but it's very messy, because in this way I need to set a watcher for every validation that I'll add to the form.
1

After deep checking of the directive behavior. I find out that the scope.input of the last element infect all the others scopes.
So I set the $watch to listen to ctrl.$error, and it solved the problem.

The directive:

module.directive('validator', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) {
      scope.$watch(function() {return ctrl.$error}, function() {
        if (ctrl.$invalid) {
            console.log(attr.name, 'invalid');
        }
        else {
            console.log(attr.name, 'valid');
        }
      }, true);
    }
  }
}]);

Updated JSFiddle

1 Comment

yes now you can have control on ctrl.$error object .
0

You're doing this to display error messages? Why not simply do this in the template?

<form name="myform">
  <input ng-model="myform.model.user-name" name="user-name" id="my-form-user-name" />
  <div ng-messages="myform.user-name.$error">
    <p ng-if="myform.user-name.$invalid">My Error Message Here</p>
  </div>
</div>

1 Comment

Because I want to use tooltips to display the errors

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.