Multi Checkbox Validation

by Himanshu Joshi

HTML

<script type="text/javascript" src="http://code.angularjs.org/angular-1.0.0rc8.min.js"></script>
<div ng-app="app">
<div ng-controller="Ctrl">
    <form name="theForm">
        <my-checkboxes ng-model="field"></my-checkboxes>
            <div ng-show="theForm.$valid">valid</div>
            <div ng-hide="theForm.$valid">invalid</div>
    </form>
</div>
</div>

JavaScript

function Ctrl($scope) {
    $scope.field = {
        name:'multi checkboxes',
        value:'',
        required:true,
        options:[
            {value:'option 1'},
            {value:'option 2'},
            {value:'option 3'}
        ]
    };
}

var app = angular.module('app',[]).directive('myCheckboxes', function(){
    return {
        restrict: 'E',
        require: 'ngModel',
        scope: { ngModel: 'accessor' },
        template: '<div ng-repeat="option in ngModel().options">'
            +'<label>'
            +'<input type="checkbox" ng-model="cbModel[option.value]" '
            +'value="{{option.value}}" ng-change="update()" ng-required="isRequired()"/>'
            +'{{option.value}}'            
            +'</label>'                
            +'</div>',
        link: function(scope, element, attrs, ctrl){
            scope.cbModel= {};
            
            ctrl.$parsers.unshift(function(value){
                for (var c in scope.cbModel) {
                    if (scope.cbModel[c]) {
                        ctrl.$setValidity('checkbox', true);
                    }
                }
                ctrl.$setValidity('checkbox', false);
            });
            
            scope.update = function(){
                var val = [];
                angular.forEach(scope.cbModel, function(v,k){
                    if (v)
                        val.push(k);
                });
                if (val.length>0)
                    scope.ngModel().value = angular.toJson(val);
            };
            
            scope.isRequired = function(){
                if (!scope.ngModel().required) return false;
                
                return scope.ngModel().required;
            };
        }
    };
});