Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skip nested forms validation with AngularJS

How can I skip validation of nested forms with AngularJS? I have to make an outer form valid even when its child form is invalid.

In the example below outer form should be valid (fOuter.$valid must be true). By default, it is not. Is there an option?

Code (jsFiddle):

<div ng-app ng-controller="Ctrl">       <ng-form name="fOuter">           <h3>Outer form (valid={{fOuter.$valid}})</h3>           <input type="text" name="txtOuter" ng-model="outer" placeholder="(required)" required />           <ng-form name="fInner">               <h3>Inner form (valid={{fInner.$valid}})</h3>               <input type="text" name="txtInner" ng-model="inner" placeholder="(required)" required />           </ng-form>       </ng-form>   </div> 
like image 259
Antelle Avatar asked Oct 12 '13 11:10

Antelle


1 Answers

Here is my solution inspired by mbernath, that isolates completely the form itself from its father.

This solution take care of the:

  • Form validity ($valid, $invalid)
  • Form interaction ($pristine, $dirty)
  • Nested forms validity and interaction

See it in action in this JSFiddle.

angular.module('isolateForm',[]).directive('isolateForm', [function () {     return {         restrict: 'A',         require: '?form',         link: function (scope, elm, attrs, ctrl) {             if (!ctrl) {                 return;             }              // Do a copy of the controller             var ctrlCopy = {};             angular.copy(ctrl, ctrlCopy);              // Get the parent of the form             var parent = elm.parent().controller('form');             // Remove parent link to the controller             parent.$removeControl(ctrl);              // Replace form controller with a "isolated form"             var isolatedFormCtrl = {                 $setValidity: function (validationToken, isValid, control) {                     ctrlCopy.$setValidity(validationToken, isValid, control);                     parent.$setValidity(validationToken, true, ctrl);                 },                 $setDirty: function () {                     elm.removeClass('ng-pristine').addClass('ng-dirty');                     ctrl.$dirty = true;                     ctrl.$pristine = false;                 },             };             angular.extend(ctrl, isolatedFormCtrl);         }     }; }]); 

To use it just call the directive "isolate-form" :

<form name="parent">     <input type="text" ng-model="outside"/>     <ng-form name="subform" isolate-form>         <input type="text" ng-model="inside"/>     </ng-form> </form> 
like image 123
91K00 Avatar answered Sep 24 '22 22:09

91K00