Ruben Rocco De Luca Ruben Rocco De Luca - 1 month ago 7
HTML Question

Form element directive with error message manage AngularJS

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

Answer

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>
Comments