1

Hello I have a problem with my validation directive. First of all I have directive that creates input element, in which I have directives that are based on some parameters that tell if this calidation should be fired up or not... It looks like this:

app.directive('ngAttr', function($compile){
return {
    scope:{},
    link: function (scope, element, attrs){
        var opts = scope.$eval(attrs.ngAttr);

        if(opts.condition){
            element.attr(opts.attrName, opts.condition)
        }
    }
};

});

It adds attribute based on condition passed to it... If I want to add a directive conditionally I do:

ng-attr="{condition: {{opts.validatePhone}}, attrName:'validate-phone'}" 

as an attribute tu my previous directive that creates an input... And the problem is that the validate-phone directive is fired up only once when the directive is created it doen't react on input handlers... The code of validate directive is:

app.directive('validatePhone', function($compile){
return{
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel){

        function validate(val){
            console.log(val)
        }

        scope.$watch(function() {
            return ngModel.$viewValue;
        }, validate);

    }
};

});

Not it is simple but console.log() dosn't work when I change input.

I created a plunker so it will be easier to check it if someone has an idea... http://plnkr.co/edit/CgVCV58goFS9GKLBtRrw?p=preview

Adrian Wajs
  • 137
  • 1
  • 3
  • 11
  • Ok I logged scope of validatePhone directive and it isn't scope that is applied to form-input directive but parent scope hmmm why... – Adrian Wajs Feb 14 '14 at 10:38

1 Answers1

0

I don't believe the $watch function is set up correctly.

It would help if you could be a little more specific in what you wish to do in the directive with the validation function.

Here is the link to the Angularjs docs on $watch.

[$watch][1]

Notice how the watch expression is a property of scope. You don't include anything in your $watch function. You are saying 'SCOPE' please 'WATCH' function.

What you should be saying is

'SCOPE' please 'WATCH' this property called 'enter scope property here' and execute this function when it changes, or some other custom logic.

I think it's mostly that your are not watching anything. You need to watch the ng-model(s) of whatever you with to update.

Change your function to this...

  scope.$watch(attrs.ngModel, function( elementValue ) {
    if( !elementValue ){ return; } // return if falsy.
    if( validate( elementValue )){ return elementValue; }
    }); // or something like this.

If you don't know the value of each ng-model, because perhaps they are created dynamically using ng-repeat, and unknown values from the server you could do something like this to watch something.

app.directive('mydirective', function(){

  return {
    restrict:'A', // Declares an Attributes Directive.
    require: '?ngModel', // ? checks for parent scope if one exists.

    link: function( scope, elem, attrs, ngModel ){
      if( !ngModel ){ return };

      scope.$watch(attrs.ngModel, function(value){
        if( !value ) { return };
        // do something with validation of ngModel.
      });
    }
  }
});

Then in your HTML

<input type="text" ng-model="{{ dynamicValue }}" my-directive />

or

<input type="text" ng-model="{{ dynamicValue }}" my-directive="myFunctionName()" />

You would have to add a little to the directive to run the function though. probably isolate the scope like

scope: {
  myDirective: '&'
}

Then in the directive $watch you could run it like

scope.myDirective();

Something like this I think.

Also, there are many ways to validate using Angularjs. Here is another link.

Here is one way

There are several ways to connect the validation.

You can $watch its model, You can add your function to fire on some event (blur, click, focus, etc...) Or just run the function when the directive loads by just calling your validation function validate( value );

Community
  • 1
  • 1
SoEzPz
  • 14,958
  • 8
  • 61
  • 64