1

I have the following code, note the name-valid and validation-function tags on the input field.

<form name="createForm" novalidate>
    <div style="display: flex; width: 300px">
        <div style="flex: 3;">
            Name
        </div>
        <div style="flex: 5;">
            <input type="text" name="listName" ng-model="newListName" 
            ng-minlength="3" name-valid validation-function="someFunction"/>
        </div>
    </div>
    <div ng-show="createForm.listName.$error.unique &&
                  !renameGoldenForm.listName.$error.minlength">already exists</div>
    <div ng-show="createForm.listName.$error.minlength">too short</div>
    <div style="margin-top: 10px">
        <button ng-click="createList()" ng-disabled="createForm.listName.$invalid">
         Create</button>
    </div>
</form>

And here is the JS:

window.angular.module("myModule").directive("nameValid", [
    "$log",
    function($log) {
        return {
            require: "ngModel",
            scope: {
                validationFunction: "="
            },
            link: function(scope, ele, attrs, c) {
                scope.$watch(attrs.ngModel, function() {
                    var v = scope[attrs.ngModel];
                    if (!v || !((v).trim()) || v.length < 4) {
                       c.$setValidity("unique", true);
                       c.$setValidity("minlength", false);
                        return;
                    }
                    scope.validationFunction(v, scope.selectedListId)
                        .success(function(data) {
                            c.$setValidity("unique", data.unique);
                            c.$setValidity("minlength", data.minlength);
                        });
                });
            }
        };
    }
]);

The problem is that having require and scope seems to break. Is there a way to pass a custom validate function to my directive? I'm not sure how to go about it. I've tried removing require: 'ngModel' and adding ngModel in scope, but that did not work either. If I remove scope and hard code the function in the watch block, that works, but obviously, that defeats the purpose of having a pointer to a specific function.

1 Answer 1

1

To bind a controller function to your directive, you have to use the & bindings (expression binding) which allows the directive to call an expression or a function defined by a DOM attribute.

For example :

Controller

(function(){

function Controller($scope, $q) {

  //Declare the func which will be bind to the directive
  $scope.func = function (data1, data2) {
    return new $q(function(resolve){
      resolve(data1 === data2);
    });
   }

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

Then we will bind this function into your directive, and we can call it into the link function.

Directive

(function(){

  function directive() {
      return{
        restrict: 'AE',
        scope: {
          function: '&'
        },
        link:function(scope, element, attrs) {
          //Then, pass an object as argument to your function
          var promise = scope.function({data1: 5, data2: 5});

          //Retrieve result
          promise.then(function(data){
            console.log(data);
          });
        }
      };
  }

angular
  .module('app')
  .directive('directive', directive);

})();

To finish, you can call your directive with a function attribute, in order to bind the function to your directive.

HTML

  <body ng-app="app" ng-controller="ctrl">

      <directive function="func(data1, data2)"></directive>

 </body>
Sign up to request clarification or add additional context in comments.

Comments

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.