1/** 2 * Checklist-model 3 * AngularJS directive for list of checkboxes 4 */ 5 6angular.module('checklist-model', []) 7.directive('checklistModel', function($parse, $compile) { 8 // contains 9 function contains(arr, item) { 10 if (angular.isArray(arr)) { 11 for (var i = 0; i < arr.length; i++) { 12 if (angular.equals(arr[i], item)) { 13 return true; 14 } 15 } 16 } 17 return false; 18 } 19 20 // add 21 function add(arr, item) { 22 arr = angular.isArray(arr) ? arr : []; 23 for (var i = 0; i < arr.length; i++) { 24 if (angular.equals(arr[i], item)) { 25 return; 26 } 27 } 28 arr.push(item); 29 } 30 31 // remove 32 function remove(arr, item) { 33 if (angular.isArray(arr)) { 34 for (var i = 0; i < arr.length; i++) { 35 if (angular.equals(arr[i], item)) { 36 arr.splice(i, 1); 37 return; 38 } 39 } 40 } 41 } 42 43 return { 44 restrict: 'A', 45 scope: true, 46 link: function(scope, elem, attrs) { 47 if (elem[0].tagName !== 'INPUT' || !elem.attr('type', 'checkbox')) { 48 throw 'checklist-model should be applied to `input[type="checkbox"]`.'; 49 } 50 51 if (!attrs.checklistValue) { 52 throw 'You should provide `checklist-value`.'; 53 } 54 55 var modelGet = $parse(attrs.checklistModel); 56 var modelSet = modelGet.assign; 57 var model = modelGet(scope); 58 var value = $parse(attrs.checklistValue)(scope); 59 60 // local var storing individual checkbox model 61 scope.checked = contains(model, value); 62 63 // exclude recursion 64 elem.removeAttr('checklist-model'); 65 elem.attr('ng-model', 'checked'); 66 $compile(elem)(scope); 67 68 // watch UI checked change 69 scope.$watch('checked', function(newValue, oldValue) { 70 if (newValue === oldValue) { 71 return; 72 } if (newValue === true) { 73 add(model, value); 74 modelSet(scope.$parent, model); 75 } else if (newValue === false) { 76 remove(model, value); 77 modelSet(scope.$parent, model); 78 } 79 }); 80 81 // watch element destroy to remove from model 82 elem.bind('$destroy', function() { 83 remove(model, value); 84 modelSet(scope.$parent, model); 85 }); 86 87 // watch model change 88 scope.$watch(function ngModelWatch() { 89 var curModel = modelGet(scope); 90 if (model !== curModel) { 91 model = curModel; 92 scope.checked = contains(model, value); 93 } 94 }); 95 } 96 }; 97});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.