PageSourceSearch

https://social.brussels/webjars/checklist-model/0.9.0/checklist-model.js

js social.brussels collected 2026-10-02 15:38:29 UTC 4,850 bytes, 156 lines download raw bytes

vendor: 4,424 bytes, lines 1-140
1/**
2 * Checklist-model
3 * AngularJS directive for list of checkboxes
4 * https://github.com/vitalets/checklist-model
5 * License: MIT http://opensource.org/licenses/MIT
6 */
7
8angular.module('checklist-model', [])
9.directive('checklistModel', ['$parse', '$compile', function($parse, $compile) {
10  // contains
11  function contains(arr, item, comparator) {
12    if (angular.isArray(arr)) {
13      for (var i = arr.length; i--;) {
14        if (comparator(arr[i], item)) {
15          return true;
16        }
17      }
18    }
19    return false;
20  }
21
22  // add
23  function add(arr, item, comparator) {
24    arr = angular.isArray(arr) ? arr : [];
25      if(!contains(arr, item, comparator)) {
26          arr.push(item);
27      }
28    return arr;
29  }  
30
31  // remove
32  function remove(arr, item, comparator) {
33    if (angular.isArray(arr)) {
34      for (var i = arr.length; i--;) {
35        if (comparator(arr[i], item)) {
36          arr.splice(i, 1);
37          break;
38        }
39      }
40    }
41    return arr;
42  }
43
44  // http://stackoverflow.com/a/19228302/1458162
45  function postLinkFn(scope, elem, attrs) {
46     // exclude recursion, but still keep the model
47    var checklistModel = attrs.checklistModel;
48    attrs.$set("checklistModel", null);
49    // compile with `ng-model` pointing to `checked`
50    $compile(elem)(scope);
51    attrs.$set("checklistModel", checklistModel);
52
53    // getter for original model
54    var checklistModelGetter = $parse(checklistModel);
55    var checklistChange = $parse(attrs.checklistChange);
56    var checklistBeforeChange = $parse(attrs.checklistBeforeChange);
57    var ngModelGetter = $parse(attrs.ngModel);
58
59
60
61    var comparator = angular.equals;
62
63    if (attrs.hasOwnProperty('checklistComparator')){
64      if (attrs.checklistComparator[0] == '.') {
65        var comparatorExpression = attrs.checklistComparator.substring(1);
66        comparator = function (a, b) {
67          return a[comparatorExpression] === b[comparatorExpression];
68        };
69        
70      } else {
71        comparator = $parse(attrs.checklistComparator)(scope.$parent);
72      }
73    }
74
75    // watch UI checked change
76    scope.$watch(attrs.ngModel, function(newValue, oldValue) {
77      if (newValue === oldValue) { 
78        return;
79      }
80
81      if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) {
82        ngModelGetter.assign(scope, contains(checklistModelGetter(scope.$parent), getChecklistValue(), comparator));
83        return;
84      }
85
86      setValueInChecklistModel(getChecklistValue(), newValue);
87
88      if (checklistChange) {
89        checklistChange(scope);
90      }
91    });
92
93    // watches for value change of checklistValue (Credit to @blingerson)
94    scope.$watch(getChecklistValue, function(newValue, oldValue) {
95      if( newValue != oldValue && angular.isDefined(oldValue) && scope[attrs.ngModel] === true ) {
96        var current = checklistModelGetter(scope.$parent);
97        checklistModelGetter.assign(scope.$parent, remove(current, oldValue, comparator));
98        checklistModelGetter.assign(scope.$parent, add(current, newValue, comparator));
99      }
100    });
101
102    function getChecklistValue() {
103      return attrs.checklistValue ? $parse(attrs.checklistValue)(scope.$parent) : attrs.value;
104    }
105    
106    function setValueInChecklistModel(value, checked) {
107      var current = checklistModelGetter(scope.$parent);
108      if (angular.isFunction(checklistModelGetter.assign)) {
109        if (checked === true) {
110          checklistModelGetter.assign(scope.$parent, add(current, value, comparator));
111        } else {
112          checklistModelGetter.assign(scope.$parent, remove(current, value, comparator));
113        }
114      }
115      
116    }
117
118    // declare one function to be used for both $watch functions
119    function setChecked(newArr, oldArr) {
120      if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) {
121        setValueInChecklistModel(getChecklistValue(), ngModelGetter(scope));
122        return;
123      }
124      ngModelGetter.assign(scope, contains(newArr, getChecklistValue(), comparator));
125    }
126
127    // watch original model change
128    // use the faster $watchCollection method if it's available
129    if (angular.isFunction(scope.$parent.$watchCollection)) {
130        scope.$parent.$watchCollection(checklistModel, setChecked);
131    } else {
132        scope.$parent.$watch(checklistModel, setChecked, true);
133    }
134  }
135
136  return {
137    restrict: 'A',
138    priority: 1000,
139    terminal: true,
140    scope: true,
141    compile: function(tElement, tAttrs) {
142
143      if (!tAttrs.checklistValue && !tAttrs.value) {
144        throw 'You should provide `value` or `checklist-value`.';
145      }
146
147      // by default ngModel is 'checked', so we set it if not specified
148      if (!tAttrs.ngModel) {
149        // local scope var storing individual checkbox model
150        tAttrs.$set("ngModel", "checked");
151      }
152
153      return postLinkFn;
154    }
155  };
156}]);

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.