Angular: Empty Fiddle

http://angularjs.org/

HTML

<script src="http://code.angularjs.org/angular-1.0.1.js"></script>
<div ng-controller="MyCtrl">
  <checkbox3 ng-model='state' ng-change='onChange(state)'/>
</div>

JavaScript

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

myApp.directive('checkbox3', function() {
        return {
            restrict: 'EA',
            replace: true,
            template: "<input type='checkbox'/>",
            require: '^ngModel',
            link: function (scope, element, attrs, ngModel) {
                function apply(state) {
                    switch (state) {
                        case false:
                            element.attr('unchecked', true);
                            element.attr('checked', null);
                            element.prop('indeterminate', false);
                            break;
                        case true:
                            element.attr('unchecked', null);
                            element.attr('checked', true);
                            element.prop('indeterminate', false);
                            break;
                        case 'unknown':
                            element.attr('unchecked', null);
                            element.attr('checked', null);
                            element.prop('indeterminate', true);
                            break;
                    }
                }

                var states = [false, true, 'unknown'];
                element.bind('change', function () {
                    // De-active angularjs default validation that only accepts true/false
                    element.unbind('click');
                    
                    // De-activate the default parser that converts 'unknown' to true.
                    ngModel.$parsers = [];

                    var state = ngModel.$viewValue;
                    state = states[(states.indexOf(state) + 1) % 3];
                    apply(state);
                    ngModel.$setViewValue(state);
                });
            }
        };
    });


function MyCtrl($scope) {
    $scope.state = 'false';
    
    $scope.onChange = function(state) {
        console.log(state);
    }
}