AngularJS - Isolated subform validation
Isolated Subform validation
by Jamseer Noordeen
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<div data-ng-app="demoApp" data-ng-controller="nestedFormIsolation" class="main">
<div class="bg-info wrapper">
<h4>
Parent Form
<span data-ng-if="parentForm.$invalid" class="label label-danger">NG-INVALID</span>
<span data-ng-if="parentForm.$valid" class="label label-success">NG-VALID</span>
<span data-ng-if="parentForm.$pristine" class="label label-info">NG-PRISTINE</span>
<span data-ng-if="parentForm.$dirty" class="label label-warning">NG-DIRTY</span>
</h4>
<ng-form name="parentForm">
<br>
<input type="text" required data-ng-model="input1" name="input1" />
<span data-ng-if="parentForm.input1.$invalid" class="label label-danger">NG-INVALID</span>
<span data-ng-if="parentForm.input1.$valid" class="label label-success">NG-VALID</span>
<span data-ng-if="parentForm.input1.$pristine" class="label label-info">NG-PRISTINE</span>
<span data-ng-if="parentForm.input1.$dirty" class="label label-warning">NG-DIRTY</span>
<br>
<br>
<a class="btn btn-default btn-xs" data-ng-click="setPristine(parentForm)">Set pristine</a>
<div class="indent-block">
<div class="bg-success wrapper">
<h4>
Isolated subform
<span data-ng-if="isolatedForm.$invalid" class="label label-danger">NG-INVALID</span>
<span data-ng-if="isolatedForm.$valid" class="label label-success">NG-VALID</span>
<span data-ng-if="isolatedForm.$pristine" class="label label-info">NG-PRISTINE</span>
<span data-ng-if="isolatedForm.$dirty" class="label label-warning">NG-DIRTY</span>
</h4>
<ng-form name="isolatedForm" data-isolate-form>
<br>
<input type="text" required data-ng-model="input2" name="input2" />
<span data-ng-if="isolatedForm.input2.$invalid"...
CSS
.main {
margin: 10px;
font-size: 12px;
}
.wrapper {
padding: 10px;
margin-top: 10px;
}
.indent-block {
padding-left: 30px;
}
.help-block {
display: inline-block;
}
input.ng-invalid {
border-color: red;
border-width: 1px;
}
input.ng-valid {
border-color: blue;
border-width: 1px;
}
JavaScript
var demoApp = angular.module('demoApp', []);
demoApp.controller('nestedFormIsolation', function($scope) {
$scope.setPristine = function(form) {
form.$setPristine();
};
});
demoApp.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);
}
};
}]);