rails-angularstrap 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +89 -0
  3. data/Rakefile +2 -0
  4. data/lib/rails/angularstrap.rb +8 -0
  5. data/lib/rails/angularstrap/version.rb +5 -0
  6. data/vendor/assets/javascripts/angular-strap/LICENSE.md +21 -0
  7. data/vendor/assets/javascripts/angular-strap/README.md +112 -0
  8. data/vendor/assets/javascripts/angular-strap/angular-strap.nuspec +23 -0
  9. data/vendor/assets/javascripts/angular-strap/bower.json +53 -0
  10. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.js +5014 -0
  11. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js +11 -0
  12. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js.map +1 -0
  13. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.js +89 -0
  14. data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.min.js +8 -0
  15. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.js +249 -0
  16. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js +9 -0
  17. data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js.map +1 -0
  18. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.js +120 -0
  19. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js +9 -0
  20. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js.map +1 -0
  21. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.js +14 -0
  22. data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.min.js +8 -0
  23. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.js +96 -0
  24. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js +9 -0
  25. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js.map +1 -0
  26. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.js +14 -0
  27. data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.min.js +8 -0
  28. data/vendor/assets/javascripts/angular-strap/dist/modules/button.js +177 -0
  29. data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js +9 -0
  30. data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js.map +1 -0
  31. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.js +273 -0
  32. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js +9 -0
  33. data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js.map +1 -0
  34. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.js +61 -0
  35. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js +9 -0
  36. data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js.map +1 -0
  37. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.js +273 -0
  38. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js +9 -0
  39. data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js.map +1 -0
  40. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.js +640 -0
  41. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js +9 -0
  42. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js.map +1 -0
  43. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.js +14 -0
  44. data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.min.js +8 -0
  45. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.js +62 -0
  46. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js +9 -0
  47. data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js.map +1 -0
  48. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.js +156 -0
  49. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js +9 -0
  50. data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js.map +1 -0
  51. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.js +149 -0
  52. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js +9 -0
  53. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js.map +1 -0
  54. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.js +14 -0
  55. data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.min.js +8 -0
  56. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.js +349 -0
  57. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js +9 -0
  58. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js.map +1 -0
  59. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.js +14 -0
  60. data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.min.js +8 -0
  61. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.js +72 -0
  62. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js +9 -0
  63. data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js.map +1 -0
  64. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.js +76 -0
  65. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js +9 -0
  66. data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js.map +1 -0
  67. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.js +112 -0
  68. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js +9 -0
  69. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js.map +1 -0
  70. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.js +14 -0
  71. data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.min.js +8 -0
  72. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.js +61 -0
  73. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js +9 -0
  74. data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js.map +1 -0
  75. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.js +261 -0
  76. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js +9 -0
  77. data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js.map +1 -0
  78. data/vendor/assets/javascripts/angular-strap/dist/modules/select.js +325 -0
  79. data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js +9 -0
  80. data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js.map +1 -0
  81. data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.js +14 -0
  82. data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.min.js +8 -0
  83. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.js +186 -0
  84. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js +9 -0
  85. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js.map +1 -0
  86. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.js +14 -0
  87. data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.min.js +8 -0
  88. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.js +485 -0
  89. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js +9 -0
  90. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js.map +1 -0
  91. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.js +14 -0
  92. data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.min.js +8 -0
  93. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.js +690 -0
  94. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js +9 -0
  95. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js.map +1 -0
  96. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.js +14 -0
  97. data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.min.js +8 -0
  98. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.js +266 -0
  99. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js +9 -0
  100. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js.map +1 -0
  101. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.js +14 -0
  102. data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.min.js +8 -0
  103. data/vendor/assets/javascripts/angular-strap/gulpfile.js +489 -0
  104. data/vendor/assets/javascripts/angular-strap/package.json +73 -0
  105. data/vendor/assets/javascripts/angular-strap/src/affix/affix.js +258 -0
  106. data/vendor/assets/javascripts/angular-strap/src/alert/alert.js +113 -0
  107. data/vendor/assets/javascripts/angular-strap/src/alert/alert.tpl.html +4 -0
  108. data/vendor/assets/javascripts/angular-strap/src/aside/aside.js +89 -0
  109. data/vendor/assets/javascripts/angular-strap/src/aside/aside.tpl.html +14 -0
  110. data/vendor/assets/javascripts/angular-strap/src/button/button.js +174 -0
  111. data/vendor/assets/javascripts/angular-strap/src/collapse/collapse.js +266 -0
  112. data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.js +633 -0
  113. data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.tpl.html +33 -0
  114. data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.js +143 -0
  115. data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.tpl.html +6 -0
  116. data/vendor/assets/javascripts/angular-strap/src/helpers/date-formatter.js +54 -0
  117. data/vendor/assets/javascripts/angular-strap/src/helpers/date-parser.js +266 -0
  118. data/vendor/assets/javascripts/angular-strap/src/helpers/debounce.js +55 -0
  119. data/vendor/assets/javascripts/angular-strap/src/helpers/dimensions.js +212 -0
  120. data/vendor/assets/javascripts/angular-strap/src/helpers/parse-options.js +69 -0
  121. data/vendor/assets/javascripts/angular-strap/src/helpers/raf.js +54 -0
  122. data/vendor/assets/javascripts/angular-strap/src/modal/modal.js +348 -0
  123. data/vendor/assets/javascripts/angular-strap/src/modal/modal.tpl.html +14 -0
  124. data/vendor/assets/javascripts/angular-strap/src/module.js +19 -0
  125. data/vendor/assets/javascripts/angular-strap/src/navbar/navbar.js +65 -0
  126. data/vendor/assets/javascripts/angular-strap/src/popover/popover.js +111 -0
  127. data/vendor/assets/javascripts/angular-strap/src/popover/popover.tpl.html +5 -0
  128. data/vendor/assets/javascripts/angular-strap/src/scrollspy/scrollspy.js +254 -0
  129. data/vendor/assets/javascripts/angular-strap/src/select/select.js +321 -0
  130. data/vendor/assets/javascripts/angular-strap/src/select/select.tpl.html +14 -0
  131. data/vendor/assets/javascripts/angular-strap/src/tab/tab.js +183 -0
  132. data/vendor/assets/javascripts/angular-strap/src/tab/tab.tpl.html +7 -0
  133. data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.js +493 -0
  134. data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.tpl.html +62 -0
  135. data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.js +806 -0
  136. data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.tpl.html +4 -0
  137. data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.js +262 -0
  138. data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.tpl.html +5 -0
  139. data/vendor/assets/javascripts/angular/README.md +64 -0
  140. data/vendor/assets/javascripts/angular/angular-csp.css +13 -0
  141. data/vendor/assets/javascripts/angular/angular.js +26181 -0
  142. data/vendor/assets/javascripts/angular/angular.min.js +250 -0
  143. data/vendor/assets/javascripts/angular/angular.min.js.gzip +0 -0
  144. data/vendor/assets/javascripts/angular/angular.min.js.map +8 -0
  145. data/vendor/assets/javascripts/angular/bower.json +8 -0
  146. data/vendor/assets/javascripts/angular/index.js +2 -0
  147. data/vendor/assets/javascripts/angular/package.json +25 -0
  148. metadata +237 -0
@@ -0,0 +1,321 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])
4
+
5
+ .provider('$select', function() {
6
+
7
+ var defaults = this.defaults = {
8
+ animation: 'am-fade',
9
+ prefixClass: 'select',
10
+ prefixEvent: '$select',
11
+ placement: 'bottom-left',
12
+ template: 'select/select.tpl.html',
13
+ trigger: 'focus',
14
+ container: false,
15
+ keyboard: true,
16
+ html: false,
17
+ delay: 0,
18
+ multiple: false,
19
+ allNoneButtons: false,
20
+ sort: true,
21
+ caretHtml: '&nbsp;<span class="caret"></span>',
22
+ placeholder: 'Choose among the following...',
23
+ allText: 'All',
24
+ noneText: 'None',
25
+ maxLength: 3,
26
+ maxLengthHtml: 'selected',
27
+ iconCheckmark: 'glyphicon glyphicon-ok'
28
+ };
29
+
30
+ this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {
31
+
32
+ var bodyEl = angular.element($window.document.body);
33
+ var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);
34
+ var isTouch = ('createTouch' in $window.document) && isNative;
35
+
36
+ function SelectFactory(element, controller, config) {
37
+
38
+ var $select = {};
39
+
40
+ // Common vars
41
+ var options = angular.extend({}, defaults, config);
42
+
43
+ // parse sort option value to support attribute as string
44
+ // when binded to interpolated value
45
+ options.sort = options.sort.toString().match(/true|1/i);
46
+
47
+ $select = $tooltip(element, options);
48
+ var scope = $select.$scope;
49
+
50
+ scope.$matches = [];
51
+ scope.$activeIndex = 0;
52
+ scope.$isMultiple = options.multiple;
53
+ scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;
54
+ scope.$iconCheckmark = options.iconCheckmark;
55
+ scope.$allText = options.allText;
56
+ scope.$noneText = options.noneText;
57
+
58
+ scope.$activate = function(index) {
59
+ scope.$$postDigest(function() {
60
+ $select.activate(index);
61
+ });
62
+ };
63
+
64
+ scope.$select = function(index, evt) {
65
+ scope.$$postDigest(function() {
66
+ $select.select(index);
67
+ });
68
+ };
69
+
70
+ scope.$isVisible = function() {
71
+ return $select.$isVisible();
72
+ };
73
+
74
+ scope.$isActive = function(index) {
75
+ return $select.$isActive(index);
76
+ };
77
+
78
+ scope.$selectAll = function () {
79
+ for (var i = 0; i < scope.$matches.length; i++) {
80
+ if (!scope.$isActive(i)) {
81
+ scope.$select(i);
82
+ }
83
+ }
84
+ };
85
+
86
+ scope.$selectNone = function () {
87
+ for (var i = 0; i < scope.$matches.length; i++) {
88
+ if (scope.$isActive(i)) {
89
+ scope.$select(i);
90
+ }
91
+ }
92
+ };
93
+
94
+ // Public methods
95
+
96
+ $select.update = function(matches) {
97
+ scope.$matches = matches;
98
+ $select.$updateActiveIndex();
99
+ };
100
+
101
+ $select.activate = function(index) {
102
+ if(options.multiple) {
103
+ $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);
104
+ if(options.sort) scope.$activeIndex.sort();
105
+ } else {
106
+ scope.$activeIndex = index;
107
+ }
108
+ return scope.$activeIndex;
109
+ };
110
+
111
+ $select.select = function(index) {
112
+ var value = scope.$matches[index].value;
113
+ scope.$apply(function() {
114
+ $select.activate(index);
115
+ if(options.multiple) {
116
+ controller.$setViewValue(scope.$activeIndex.map(function(index) {
117
+ return scope.$matches[index].value;
118
+ }));
119
+ } else {
120
+ controller.$setViewValue(value);
121
+ // Hide if single select
122
+ $select.hide();
123
+ }
124
+ });
125
+ // Emit event
126
+ scope.$emit(options.prefixEvent + '.select', value, index, $select);
127
+ };
128
+
129
+ // Protected methods
130
+
131
+ $select.$updateActiveIndex = function() {
132
+ if(controller.$modelValue && scope.$matches.length) {
133
+ if(options.multiple && angular.isArray(controller.$modelValue)) {
134
+ scope.$activeIndex = controller.$modelValue.map(function(value) {
135
+ return $select.$getIndex(value);
136
+ });
137
+ } else {
138
+ scope.$activeIndex = $select.$getIndex(controller.$modelValue);
139
+ }
140
+ } else if(scope.$activeIndex >= scope.$matches.length) {
141
+ scope.$activeIndex = options.multiple ? [] : 0;
142
+ }
143
+ };
144
+
145
+ $select.$isVisible = function() {
146
+ if(!options.minLength || !controller) {
147
+ return scope.$matches.length;
148
+ }
149
+ // minLength support
150
+ return scope.$matches.length && controller.$viewValue.length >= options.minLength;
151
+ };
152
+
153
+ $select.$isActive = function(index) {
154
+ if(options.multiple) {
155
+ return scope.$activeIndex.indexOf(index) !== -1;
156
+ } else {
157
+ return scope.$activeIndex === index;
158
+ }
159
+ };
160
+
161
+ $select.$getIndex = function(value) {
162
+ var l = scope.$matches.length, i = l;
163
+ if(!l) return;
164
+ for(i = l; i--;) {
165
+ if(scope.$matches[i].value === value) break;
166
+ }
167
+ if(i < 0) return;
168
+ return i;
169
+ };
170
+
171
+ $select.$onMouseDown = function(evt) {
172
+ // Prevent blur on mousedown on .dropdown-menu
173
+ evt.preventDefault();
174
+ evt.stopPropagation();
175
+ // Emulate click for mobile devices
176
+ if(isTouch) {
177
+ var targetEl = angular.element(evt.target);
178
+ targetEl.triggerHandler('click');
179
+ }
180
+ };
181
+
182
+ $select.$onKeyDown = function(evt) {
183
+ if (!/(9|13|38|40)/.test(evt.keyCode)) return;
184
+ evt.preventDefault();
185
+ evt.stopPropagation();
186
+
187
+ // Select with enter
188
+ if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {
189
+ return $select.select(scope.$activeIndex);
190
+ }
191
+
192
+ // Navigate with keyboard
193
+ if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;
194
+ else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;
195
+ else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;
196
+ scope.$digest();
197
+ };
198
+
199
+ // Overrides
200
+
201
+ var _show = $select.show;
202
+ $select.show = function() {
203
+ _show();
204
+ if(options.multiple) {
205
+ $select.$element.addClass('select-multiple');
206
+ }
207
+ // use timeout to hookup the events to prevent
208
+ // event bubbling from being processed imediately.
209
+ $timeout(function() {
210
+ $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);
211
+ if(options.keyboard) {
212
+ element.on('keydown', $select.$onKeyDown);
213
+ }
214
+ }, 0, false);
215
+ };
216
+
217
+ var _hide = $select.hide;
218
+ $select.hide = function() {
219
+ $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);
220
+ if(options.keyboard) {
221
+ element.off('keydown', $select.$onKeyDown);
222
+ }
223
+ _hide(true);
224
+ };
225
+
226
+ return $select;
227
+
228
+ }
229
+
230
+ SelectFactory.defaults = defaults;
231
+ return SelectFactory;
232
+
233
+ };
234
+
235
+ })
236
+
237
+ .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {
238
+
239
+ var defaults = $select.defaults;
240
+
241
+ return {
242
+ restrict: 'EAC',
243
+ require: 'ngModel',
244
+ link: function postLink(scope, element, attr, controller) {
245
+
246
+ // Directive options
247
+ var options = {scope: scope, placeholder: defaults.placeholder};
248
+ angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', 'placeholder', 'multiple', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml'], function(key) {
249
+ if(angular.isDefined(attr[key])) options[key] = attr[key];
250
+ });
251
+
252
+ // Add support for select markup
253
+ if(element[0].nodeName.toLowerCase() === 'select') {
254
+ var inputEl = element;
255
+ inputEl.css('display', 'none');
256
+ element = angular.element('<button type="button" class="btn btn-default"></button>');
257
+ inputEl.after(element);
258
+ }
259
+
260
+ // Build proper ngOptions
261
+ var parsedOptions = $parseOptions(attr.ngOptions);
262
+
263
+ // Initialize select
264
+ var select = $select(element, controller, options);
265
+
266
+ // Watch ngOptions values before filtering for changes
267
+ var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').trim();
268
+ scope.$watch(watchedOptions, function(newValue, oldValue) {
269
+ // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);
270
+ parsedOptions.valuesFn(scope, controller)
271
+ .then(function(values) {
272
+ select.update(values);
273
+ controller.$render();
274
+ });
275
+ }, true);
276
+
277
+ // Watch model for changes
278
+ scope.$watch(attr.ngModel, function(newValue, oldValue) {
279
+ // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);
280
+ select.$updateActiveIndex();
281
+ controller.$render();
282
+ }, true);
283
+
284
+ // Model rendering in view
285
+ controller.$render = function () {
286
+ // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);
287
+ var selected, index;
288
+ if(options.multiple && angular.isArray(controller.$modelValue)) {
289
+ selected = controller.$modelValue.map(function(value) {
290
+ index = select.$getIndex(value);
291
+ return angular.isDefined(index) ? select.$scope.$matches[index].label : false;
292
+ }).filter(angular.isDefined);
293
+ if(selected.length > (options.maxLength || defaults.maxLength)) {
294
+ selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);
295
+ } else {
296
+ selected = selected.join(', ');
297
+ }
298
+ } else {
299
+ index = select.$getIndex(controller.$modelValue);
300
+ selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;
301
+ }
302
+ element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));
303
+ };
304
+
305
+ if(options.multiple){
306
+ controller.$isEmpty = function(value){
307
+ return !value || value.length === 0;
308
+ };
309
+ }
310
+
311
+ // Garbage collection
312
+ scope.$on('$destroy', function() {
313
+ if (select) select.destroy();
314
+ options = null;
315
+ select = null;
316
+ });
317
+
318
+ }
319
+ };
320
+
321
+ });
@@ -0,0 +1,14 @@
1
+ <ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select">
2
+ <li ng-if="$showAllNoneButtons">
3
+ <div class="btn-group" style="margin-bottom: 5px; margin-left: 5px">
4
+ <button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button>
5
+ <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button>
6
+ </div>
7
+ </li>
8
+ <li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}">
9
+ <a style="cursor: default;" role="menuitem" tabindex="-1" ng-click="$select($index, $event)">
10
+ <i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i>
11
+ <span ng-bind="match.label"></span>
12
+ </a>
13
+ </li>
14
+ </ul>
@@ -0,0 +1,183 @@
1
+ 'use strict';
2
+
3
+ angular.module('mgcrea.ngStrap.tab', [])
4
+
5
+ .provider('$tab', function() {
6
+
7
+ var defaults = this.defaults = {
8
+ animation: 'am-fade',
9
+ template: 'tab/tab.tpl.html',
10
+ navClass: 'nav-tabs',
11
+ activeClass: 'active'
12
+ };
13
+
14
+ var controller = this.controller = function($scope, $element, $attrs) {
15
+ var self = this;
16
+
17
+ // Attributes options
18
+ self.$options = angular.copy(defaults);
19
+ angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {
20
+ if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];
21
+ });
22
+
23
+ // Publish options on scope
24
+ $scope.$navClass = self.$options.navClass;
25
+ $scope.$activeClass = self.$options.activeClass;
26
+
27
+ self.$panes = $scope.$panes = [];
28
+
29
+ // DEPRECATED: $viewChangeListeners, please use $activePaneChangeListeners
30
+ // Because we deprecated ngModel usage, we rename viewChangeListeners to
31
+ // activePaneChangeListeners to make more sense.
32
+ self.$activePaneChangeListeners = self.$viewChangeListeners = [];
33
+
34
+ self.$push = function(pane) {
35
+ self.$panes.push(pane);
36
+ };
37
+
38
+ self.$remove = function(pane) {
39
+ var index = self.$panes.indexOf(pane);
40
+ var activeIndex = self.$panes.$active;
41
+
42
+ // remove pane from $panes array
43
+ self.$panes.splice(index, 1);
44
+
45
+ if (index < activeIndex) {
46
+ // we removed a pane before the active pane, so we need to
47
+ // decrement the active pane index
48
+ activeIndex--;
49
+ }
50
+ else if (index === activeIndex && activeIndex === self.$panes.length) {
51
+ // we remove the active pane and it was the one at the end,
52
+ // so select the previous one
53
+ activeIndex--;
54
+ }
55
+ self.$setActive(activeIndex);
56
+ };
57
+
58
+ self.$panes.$active = 0;
59
+ self.$setActive = $scope.$setActive = function(value) {
60
+ self.$panes.$active = value;
61
+ self.$activePaneChangeListeners.forEach(function(fn) {
62
+ fn();
63
+ });
64
+ };
65
+
66
+ };
67
+
68
+ this.$get = function() {
69
+ var $tab = {};
70
+ $tab.defaults = defaults;
71
+ $tab.controller = controller;
72
+ return $tab;
73
+ };
74
+
75
+ })
76
+
77
+ .directive('bsTabs', function($window, $animate, $tab, $parse) {
78
+
79
+ var defaults = $tab.defaults;
80
+
81
+ return {
82
+ require: ['?ngModel', 'bsTabs'],
83
+ transclude: true,
84
+ scope: true,
85
+ controller: ['$scope', '$element', '$attrs', $tab.controller],
86
+ templateUrl: function(element, attr) {
87
+ return attr.template || defaults.template;
88
+ },
89
+ link: function postLink(scope, element, attrs, controllers) {
90
+
91
+ var ngModelCtrl = controllers[0];
92
+ var bsTabsCtrl = controllers[1];
93
+
94
+ // DEPRECATED: ngModel, please use bsActivePane
95
+ // 'ngModel' is deprecated bacause if interferes with form validation
96
+ // and status, so avoid using it here.
97
+ if(ngModelCtrl) {
98
+ console.warn('Usage of ngModel is deprecated, please use bsActivePane instead!');
99
+
100
+ // Update the modelValue following
101
+ bsTabsCtrl.$activePaneChangeListeners.push(function() {
102
+ ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);
103
+ });
104
+
105
+ // modelValue -> $formatters -> viewValue
106
+ ngModelCtrl.$formatters.push(function(modelValue) {
107
+ // console.warn('$formatter("%s"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);
108
+ bsTabsCtrl.$setActive(modelValue * 1);
109
+ return modelValue;
110
+ });
111
+
112
+ }
113
+
114
+ if (attrs.bsActivePane) {
115
+ // adapted from angularjs ngModelController bindings
116
+ // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730
117
+ var parsedBsActivePane = $parse(attrs.bsActivePane);
118
+
119
+ // Update bsActivePane value with change
120
+ bsTabsCtrl.$activePaneChangeListeners.push(function() {
121
+ parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);
122
+ });
123
+
124
+ // watch bsActivePane for value changes
125
+ scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {
126
+ bsTabsCtrl.$setActive(newValue * 1);
127
+ }, true);
128
+ }
129
+ }
130
+ };
131
+
132
+ })
133
+
134
+ .directive('bsPane', function($window, $animate, $sce) {
135
+
136
+ return {
137
+ require: ['^?ngModel', '^bsTabs'],
138
+ scope: true,
139
+ link: function postLink(scope, element, attrs, controllers) {
140
+
141
+ var ngModelCtrl = controllers[0];
142
+ var bsTabsCtrl = controllers[1];
143
+
144
+ // Add base class
145
+ element.addClass('tab-pane');
146
+
147
+ // Observe title attribute for change
148
+ attrs.$observe('title', function(newValue, oldValue) {
149
+ scope.title = $sce.trustAsHtml(newValue);
150
+ });
151
+
152
+ // Add animation class
153
+ if(bsTabsCtrl.$options.animation) {
154
+ element.addClass(bsTabsCtrl.$options.animation);
155
+ }
156
+
157
+ attrs.$observe('disabled', function(newValue, oldValue) {
158
+ scope.disabled = scope.$eval(newValue);
159
+ });
160
+
161
+ // Push pane to parent bsTabs controller
162
+ bsTabsCtrl.$push(scope);
163
+
164
+ // remove pane from tab controller when pane is destroyed
165
+ scope.$on('$destroy', function() {
166
+ bsTabsCtrl.$remove(scope);
167
+ });
168
+
169
+ function render() {
170
+ var index = bsTabsCtrl.$panes.indexOf(scope);
171
+ var active = bsTabsCtrl.$panes.$active;
172
+ $animate[index === active ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);
173
+ }
174
+
175
+ bsTabsCtrl.$activePaneChangeListeners.push(function() {
176
+ render();
177
+ });
178
+ render();
179
+
180
+ }
181
+ };
182
+
183
+ });