Angular - Isolated nested form

Isolated form directive in order to block event and validation propagation to upper forms

by gikoo

HTML

<link rel="stylesheet" href="//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...

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);
        }
    };
}]);