0

I'm trying to create a input directive element with validation. I'd like to manage error status in this directive.

There are 3 files

  • Index.html: uses this directive
  • textValid.js: contains directive code
  • textValid.html: contains the directive template

I create this directive

textValid.js

App.directive("textValid", function() {
    return {
        restrict: "E",
        templateUrl: "tpl/textValid.html",
        require: "?ngModel",

        scope: {
            name: "@",
            element: "=",
            model: "="
        }
    };
});

index.html

<form name="edit_form_ctrl.contract_edit_form" action="#" novalidate >
     <div class="row">
         <text-valid name="ncontract"model="edit_form_ctrl.contract.ncontract"
                     element="edit_form_ctrl.contract_edit_form.ncontract">
         </text-valid>
     </div>
</form>

and template textValid.html

<input type="text" name="name" ng-model="model" class="form-control" ng-required="true" value="{{model}}" />
     <div>pristine: {{element.$pristine}}</div> <!--is always undefined-->
     <div>Invalid: {{element.$error}}</div> <!--is always undefined-->
<span class="color-red" ng-if="element.$error.required  &&!element.$pristine">
    {{curLang.field_mandatory}}
</span>

I'm trying to get input control to check $error and $pristine value, but I cannot to achieve it.

I read all documentation and the book too, but with any results.

Does someone try to do that?

Thanks in advance

BrTkCa
  • 4,703
  • 3
  • 24
  • 45

2 Answers2

0

Try this:

<input type="text" name="name" ng-model="model" class="form-control" ng-required="true" value="{{model}}" />
     <div>pristine: {{form.name.$pristine}}</div> <!--is always undefined-->
     <div>Invalid: {{form.name.$error}}</div> <!--is always undefined-->
<span class="color-red" ng-if="element.$error.required  &&!element.$pristine">
    {{curLang.field_mandatory}}
</span>
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • this would technically work, but wouldn't really allow re-use of the `text-valid` directive in a form because there would be multiple inputs named `'name'` – plong0 Oct 20 '16 at 18:05
  • You're right... I was wrong. {{name}} is the correct value. So it can be dynamic – Ruben Rocco De Luca Oct 20 '16 at 18:15
0

If you add {{double-curlies}} around the name attribute of the input element like so:

<input type="text" name="{{name}}" ng-model="model" class="form-control" ng-required="true" />

You should be able to access the ngModelController for it from inside text-valid with $scope.form[$scope.name]

A couple other notes:

  1. using a value attribute on and element with ng-model attribute will not have an effect.

  2. you have require: '?ngModel' in your directive definition, but there is no ng-model attribute on the text-valid element. This is ok, but you won't get any ngModelController being injected unless the text-valid element has an ng-model attribute.

Edit:

Because text-valid has isolate scope, to access the FormController, you would need to require it and bind it:

App.directive("textValid", function() {
    return {
        restrict: "E",
        templateUrl: "tpl/textValid.html",
        require: "^^form",

        scope: {
            name: "@",
            element: "=",
            model: "="
        },
        link: function($scope, elem, attr, FormCtrl){
            $scope.form = FormCtrl;
            // now you should be able to access $scope.form[$scope.name]
            // (you *might* need to put any initialization that accesses it inside a $timeout to wait for it to be rendered/bound)
        }
    };
});

In template, you should then be able to access it like:

<div>pristine: {{form[name].$pristine}}</div>
<div>Invalid: {{form[name].$error}}</div>
plong0
  • 2,140
  • 1
  • 19
  • 18
  • Do you mean in link function within directive? I tried to add in textValid.js link: function($scope, element, attr, ctrl) but $scope.form[name] return a error 'cos form is null. – Ruben Rocco De Luca Oct 20 '16 at 18:25
  • ah right, text-valid has isolate scope. I've edited my answer with consideration of this. – plong0 Oct 20 '16 at 19:07
  • Thanks man! It works.... Just a question: what means these two '^^' before form?! – Ruben Rocco De Luca Oct 20 '16 at 19:14
  • Glad that it works! `^^` in the require means require from the DOM element's ancestor. `^` in require means require from the DOM element OR an ancestor. Check [Comprehensive Directive API docs](https://docs.angularjs.org/api/ng/service/$compile) under **require** in the **Directive Definition Object** section – plong0 Oct 20 '16 at 22:00
  • Thank you for all. – Ruben Rocco De Luca Oct 21 '16 at 05:36