Angular: Empty Fiddle

http://angularjs.org/

by boneskull

HTML

<script src="https://code.angularjs.org/1.1.5/angular.js"></script>
<div ng-controller="MyCtrl">
    <form name="myForm">
        <p>Invalid: {{myForm.$invalid}}</p>
        <p>Dirty: {{myForm.$dirty}}</p>
        <button ng-click="selectAll()">Select All</button>
        <button ng-click="selectNone()">Select None</button>
        <br>
        <div ng-repeat="datum in data">
            <input type="checkbox" ng-model="datum.foo.bar" validate/>Bar
            <br/>
            <input type="checkbox" ng-model="datum.foo.baz" validate/>Baz
            <br/>
            <input type="checkbox" ng-model="datum.foo.quux" validate/>Quux
            <br/>
        </div>
    </form>
</div>

CSS

form.ng-invalid {
    background: red;
}

JavaScript

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
    
    // weird data structure, but that's what we got
    $scope.data = [{
        foo: {
            bar: true,
            baz: false,
            quux: true
        }
    }];

    // just loops thru everything and sets it to true/false
    var select = function (v) {
        angular.forEach($scope.data, function (datum) {
            if (angular.isObject(datum)) {
                angular.forEach(datum, function (values) {
                    if (angular.isObject(values)) {
                        angular.forEach(values, function (value, key) {
                            values[key] = v;
                        });
                    }
                });
            }
        });
        
        // dirties form
        $scope.myForm.$setDirty();
    };

    $scope.selectAll = function () {
        select(true);
    };

    $scope.selectNone = function () {
        select(false);
    };
}

myApp.directive('validate', function () {
    return {
        require: ['ngModel', '^form'],
        link: function (scope, element, attrs, ctrls) {
            var ngModelCtrl = ctrls[0],
                formCtrl = ctrls[1];

            // custom validator asserts at least SOMETHING is selected
            ngModelCtrl.$formatters.push(function (value) {
                var valid = false;
                angular.forEach(scope.data, function (datum) {
                    if (angular.isObject(datum)) {
                        angular.forEach(datum, function (values) {
                            if (angular.isObject(values)) {
                                angular.forEach(values, function (value, key) {
                                    if (value) {
                                        valid = true;
                                    }
                                    return false;
                                });
                            }
                        });
                  ...