AngularJS multiple forms with ng-repeat validation

I use the ng form as the parent form and the child mg forms for validation with ng-repeat.

<div ng-form="form"> <div ng-repeat="field in fields"> <div ng-form="subform"><input...></div> </div> </div> 

And thus confirming:

 if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) { // Do something... } 

(this is a very simplified example, I have more different subforms for different types of input and with different names, for example, input [text] is called TextForm, input [numeric] is NumericForm, etc.)

Everything works as expected, if only on the field. But if ng-repeat generates several fields, the check runs only the last subform, others are ignored.

Is there a way to cycle through all the subforms to check if one of them is?

In addition, I check all the required fields blank:

 if ($scope.form.$error.required) { angular.forEach($scope.form.$error.required, function (object, index) { $scope.form.$error.required[index].$setDirty(); } ); } 

So, if my fields are executed as follows:

 ....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }".... 

And he marks all the subforms, even if there are many identical names with the same name.

Maybe I can do something similar with invalid fields? Although I tried a lot of things, nothing worked ...

+6
source share
1 answer

The solution to this is to create a directive that assigns the ngModelController error variable to each ng-repeat input.

The following is a possible implementation for getting the errors of each subformat. Demo

JAVASCRIPT (directive)

  .directive('ngModelError', function($parse, $timeout) { return { require: ['ngModel', 'form'], link: function(scope, elem, attr, ctrls) { var ngModel = ctrls[0], ngForm = ctrls[1], fieldGet = $parse(attr.ngModelError), fieldSet = fieldGet.assign, field = fieldGet(scope); $timeout(function() { field.$error = ngModel.$error; field.ngForm = ngForm; fieldSet(scope, field); }); } }; }); 

HTML

 <form name="form" ng-submit="submit(form, fields)" novalidate> <div ng-form="subForm" ng-repeat="field in fields" ng-class="{'has-error': subForm.$invalid && form.$dirty}"> <label class="control-label">{{field.label}}</label> <input type="{{field.type}}" placeholder="{{field.placeholder}}" ng-model="field.model" name="field" ng-required="field.isRequired" class="form-control" ng-model-error="field" /> </div> <br> <button type="submit" class="btn btn-primary">Submit</button> </form> 

JAVASCRIPT (controller)

Notice how the fields are structure:

  .controller('Ctrl', function($scope) { $scope.fields = { email: { type: 'email', placeholder: 'Enter email', isRequired: true, label: 'Email Address' }, password: { type: 'password', placeholder: 'Enter password', isRequired: true, label: 'Password' } }; $scope.submit = function(form, fields) { form.$dirty = true; if(form.$valid) { // do whatever } else { // accessing ngForm for email field console.log(fields.email.ngForm); // accessing errors for email field console.log(fields.email.$error); // accessing ngForm for password field console.log(fields.password.ngForm); // accessing errors for password field console.log(fields.password.$error); } }; }) 
+2
source

Source: https://habr.com/ru/post/973481/


All Articles