1

the validation isn't working in my formRow directive. I put a ng-form with the field name in the directive, but the [[ field ]].$invalid for example will not triggered. Does anybody know why?

Directive:

<li class="form__row" ng-form="[[ field ]]">
<div class="label">
    <label ng-class="{ 'required' : required == 'true' }" for="frm-[[ field ]]">[[ label ]]</label>
</div>
<div class="field" ng-switch="required" ng-class="{ 'field--invalid' : [[ field ]].$touched && [[ field ]].$invalid, 'field--valid': [[ field ]].$touched && [[ field ]].$valid }">
    <input ng-switch-when="true" type="[[ type ]]" name="[[ field ]]" id="frm-[[ field ]]" ng-model="record[ field ]" required>
    <input ng-switch-default type="[[ type ]]" name="[[ field ]]" id="frm-[[ field ]]" ng-model="record[ field ]" >
</div>

Directive.js

.directive('formRow', function () {
return {
    restrict: 'EA',
    templateUrl: FW.Config.submap + 'angular/_directives/formRow.html',
    replace: true,
    scope: {
        record: '=',
        type: '@',
        field: '@',
        label: '@',
        required: '@'
    },
    link: function($scope, element, attr) {
        // Wordt gezet bij form submit
        $scope.$on('record:invalid', function() {
            $scope[$scope.field].$setTouched;
        });
    }
}
})

Call from template:

<form name="formData" ng-submit="submit($event)" class="form--wide frm-login" novalidate>
    <ul>
        <form-row record="inloggen" field="emailadres" label="E-mailadres" type="email" required="true"></form-row>
        <form-row record="inloggen" field="wachtwoord" label="Wachtwoord" type="password" required="true"></form-row>
    </ul>

By the way: I use square brackets as $interpolateProvider symbols, because of the use of twig also in my templates.

1 Answer 1

1

I'm not sure this is very good idea to create such directive, but the main problem and what makes it pretty awkward is that you are using nested form directive ngForm with the same name as corresponding element. It adds up to the scope level.

You can make ngClass work properly with this expression (I warned this looks weird :) :

ng-class="{ 'field--invalid' : this[field][field].$touched && this[field][field].$invalid, 'field--valid': this[field][field].$touched && this[field][field].$valid }"

First of all note, that you don't use interpolation tags inside of expressions, so you don't need [[ ]] inside ngClass. Then in order to resolve dynamic object property by variable name you would use bracket notation, hence

this[field][field] 

Here you have:

  • this points to current scope object
  • this[field] points to the ngForm object which has the same name as defined in field for input element and parent ngForm
  • this[field][field] point to individual input element within form accessed by this[field].

Demo: http://plnkr.co/edit/zarnKqPnYw4BNQQKVy9t?p=info

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.