Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / app / fusion / external / ebz / angular_js / checklist-model.js
1 /**
2  * Checklist-model
3  * AngularJS directive for list of checkboxes
4  */
5
6 angular.module('checklist-model', [])
7 .directive('checklistModel', ['$parse', '$compile', 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 arr;
26       }
27     }
28     arr.push(item);
29     return arr;
30   }
31
32   // remove
33   function remove(arr, item) {
34     if (angular.isArray(arr)) {
35       for (var i = 0; i < arr.length; i++) {
36         if (angular.equals(arr[i], item)) {
37           arr.splice(i, 1);
38           break;
39         }
40       }
41     }
42     return arr;
43   }
44
45   // http://stackoverflow.com/a/19228302/1458162
46   function postLinkFn(scope, elem, attrs) {
47     // compile with `ng-model` pointing to `checked`
48     $compile(elem)(scope);
49
50     // getter / setter for original model
51     var getter = $parse(attrs.checklistModel);
52     var setter = getter.assign;
53
54     // value added to list
55     var value = $parse(attrs.checklistValue)(scope.$parent);
56
57     // watch UI checked change
58     scope.$watch('checked', function(newValue, oldValue) {
59       if (newValue === oldValue) {
60         return;
61       }
62       var current = getter(scope.$parent);
63       if (newValue === true) {
64         setter(scope.$parent, add(current, value));
65       } else {
66         setter(scope.$parent, remove(current, value));
67       }
68     });
69
70     // watch original model change
71     scope.$parent.$watch(attrs.checklistModel, function(newArr, oldArr) {
72       scope.checked = contains(newArr, value);
73     }, true);
74   }
75
76   return {
77     restrict: 'A',
78     priority: 1000,
79     terminal: true,
80     scope: true,
81     compile: function(tElement, tAttrs) {
82       if (tElement[0].tagName !== 'INPUT' || tAttrs.type !== 'checkbox') {
83         throw 'checklist-model should be applied to `input[type="checkbox"]`.';
84       }
85
86       if (!tAttrs.checklistValue) {
87         throw 'You should provide `checklist-value`.';
88       }
89
90       // exclude recursion
91       tElement.removeAttr('checklist-model');
92
93       // local scope var storing individual checkbox model
94       tElement.attr('ng-model', 'checked');
95
96       return postLinkFn;
97     }
98   };
99 }]);