#A - watch Pristine form state

by Krzysztof Safjanowski

HTML

<script src="https://code.angularjs.org/1.2.1/angular-route.js"></script>
<div ng-app="app">
    <div class="container">
        <p><a href="/form">form</a>, <a href="/unsaved">check unsaved</a></p>
        <div ng-view=""></div>
    </div>
</div>

CSS

form {
    padding: 4px;
}
form.ng-dirty {
    background: #edc;
}
form>div {
    margin: 8px 0;
}
form>div>label {
    display: inline-block;
    padding-right: 4px;
    width: 76px;
    text-align: right;
}

JavaScript

angular.module('app', ['ngRoute'])
    .config(function ($routeProvider, $locationProvider) {

    $locationProvider.html5Mode(true);

    $routeProvider.when('/form', {
        template: [

            '<form name="someForm" unsaved-collection="some">',
            '    <div><label>name:</label><input class="form-control" type="text" ng-model="some.name" /></div>',
            '    <div><label>surname:</label><input type="text" ng-model="some.surname" /></div>',
            '    <div><label>foo:</label><input type="text" ng-model="some.foo" /></div>',
            '    <button ng-click="setPristine()">is form should be saved?</button>',
            '</form>'

        ].join(''),
        controller: 'form'
    }).when('/unsaved', {
        template: 'another page'
    }).otherwise({
        redirectTo: '/form'
    });
})
    .controller('form', function ($scope) {
    $scope.some = {
        name: 'foo',
        surname: '',
        foo: 'bar'
    };
})
    .directive('unsavedCollection', function ($window) {
    return {
        require: '^form',
        restrict: 'A',
        link: function (scope, element, attrs, ngModelController) {
            var collection = attrs.unsavedCollection;
            var initial = angular.copy(scope[collection]);

            scope.setPristine = function () {
                $window.alert(formShouldBeSaved(scope[collection]));
            };

            scope.$watchCollection('some', function (newVal, oldValue) {
                if (newVal !== oldValue && !formShouldBeSaved()) {
                    ngModelController.$setPristine();
                }
            });

            scope.$on('$locationChangeStart', function (event) {
                var answer;
                if (formShouldBeSaved()) {
                    answer = confirm("Are you sure you want to leave this page?");
                    if (!answer) {
                        event.preventDefault();
                    }
                }
            });

          ...