github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/public/static/js/directives/directives.tristateCheckbox.js (about)

     1  var directives = directives || {};
     2  
     3  directives.tristateCheckbox = angular.module('directives.tristateCheckbox', []);
     4  
     5  directives.tristateCheckbox.directive('tristateCheckbox', function(){
     6    return {
     7      require: '?ngModel',
     8      link: function(scope, el, attrs, ctrl) {
     9        // Tri-state checkboxes can be bound to an ng-model (like a regular 
    10        // checkbox) but instead of rendering according to just true/false,
    11        // it renders according to 3 possible values for the model it's bound to
    12        var truthy = true; // checked
    13        var falsy = false; // unchecked
    14        var nully = null;  // indeterminate!
    15  
    16        ctrl.$formatters = []; 
    17        ctrl.$parsers = [];
    18  
    19        ctrl.$render = function() {
    20          var d = ctrl.$viewValue; // gets the value bound via ng-model
    21  
    22          // el is the actual DOM element bound to this instance of 
    23          // the directive - set its checked/indeterminate DOM properties
    24          // according to the value in the model
    25          el.data('checked', d);
    26          switch(d){
    27            case truthy:
    28              el.prop('indeterminate', false);
    29              el.prop('checked', true);
    30              break;
    31            case falsy:
    32              el.prop('indeterminate', false);
    33              el.prop('checked', false);
    34              break;
    35            default:
    36              el.prop('indeterminate', true);
    37          }
    38        };
    39  
    40        // Override the behavior for the click handler for the checkbox.
    41        // This is the value that will actually get sent to the getter/setter 
    42        // function for ng-model, when that option is in effect.
    43        el.bind('click', function() {
    44          var d;
    45          switch(el.data('checked')){
    46            case falsy:
    47              d = truthy;
    48              break;
    49            case truthy:
    50              d = nully;
    51              break;
    52            default:
    53              d = falsy;
    54          }
    55          ctrl.$setViewValue(d);
    56          scope.$apply(ctrl.$render);
    57        });
    58      }
    59    };
    60  })