0

I have done it correctly by taking reference fro, official docs of angularjs. But in directive's link method, when I set the validity using $setValidity() method, it does not reflects in view part using {{formname.controlname.$error.validationErrorKey}}

Please help me to track the error, or mistake that I am doing.

Thanks in advance

<form name="form" novalidate>
    URL <input  type="text" ng-model="myURL" name="myURL" my-url /> {{form.myURL.$error.myUrlError}}
    <span class="errorMessage" ng-show="form.myURL.$dirty && form.myURL.$error.myUrlError">
       please enter correct url
    </span>
</form>
validationModule.directive("myUrl", function($window) {    
    //return Directive Definition Object (DDO)
    return{
        restrict:"A",
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
            elm.bind('blur',function() {
                if (ctrl.$isEmpty(ctrl.$viewValue)) {
                    console.log('isEMpty-' + new Date());
                    ctrl.$setValidity("myUrlError", true);
                } else {
                    var URL_REGEXP= /https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,}/;
                    if (URL_REGEXP.test(ctrl.$viewValue)) {
                        console.log("valid-" + new Date());
                        ctrl.$setValidity("myUrlError", true);
                    } else {
                        console.log("invalid-" + new Date());
                        ctrl.$setValidity("myUrlError", false);
                    }
                }
            }); //end if 'blur' event listener  
        }//end of link function
    };//end of DDO      
});

3 Answers 3

1

use

scope.$apply( attrs.my-url); 

inside your blur event i.e

element.bind('blur', function () {
                    scope.$apply( attrs.attrs.my-url );
                }
            });
Sign up to request clarification or add additional context in comments.

Comments

0

Here is the problem:

elm.bind('blur',function(){

Angular know nothing about jquery events. They do not rise digest run. So you have to run it manualy by $scope.$applyAsync()

Here you can read more about applyAsync

Comments

0

In your sample you check if input is empty and if correspond to a pattern. I think your approach is so difficult for this feature. I recommend to you to see attribute ng-required and ng-pattern to do that. It's a more simple way i think

Here a plunker to illustrate it : https://plnkr.co/edit/pRqXfsjduvQGuRwDBuUL?p=preview

 URL <input  type="text" ng-model="myURL" name="myURL" required="true" ng-pattern="/https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,}/" /> {{form.myURL.$error}}

Another way is to create a custom validator : https://plnkr.co/edit/1hFMlB2IzuWpV7v8TOUP?p=preview

ctrl.$validators.myUrlValidator = function(modelValue, viewValue) {
            console.log('vbalidate')
            if(!viewValue || viewValue == "") {
              return false;
            }
            if(!URL_REGEXP.test(viewValue)){
              return false;
            }
            return true
          }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.