angular-ui-bootstrap-rails 0.10.0 → 0.11.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85f812e3f7f178e10580078d59e6a10ec3a972d8
|
4
|
+
data.tar.gz: 13e0843c45c3a3f4e49caebe5810d734f24a69c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4259ed0ada0ea8c87aade0067cbfc7c85440eab8e13b84a81c950798ef8002148807114d96a2cf7215bc6ac5a2a94f9f339ac3e36ab77420935cf41aa2344640
|
7
|
+
data.tar.gz: 87a81f50fb592b85e7be03e413abdfd32bc875751e505ade49c5dbdcdf999990740c52a2ac5a399c0f9247fbd03c05ff4abd2ddd4646e3c3f57f8ceca20e4244
|
@@ -2,11 +2,11 @@
|
|
2
2
|
* angular-ui-bootstrap
|
3
3
|
* http://angular-ui.github.io/bootstrap/
|
4
4
|
|
5
|
-
* Version: 0.
|
5
|
+
* Version: 0.11.0 - 2014-05-01
|
6
6
|
* License: MIT
|
7
7
|
*/
|
8
|
-
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.
|
9
|
-
angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]);
|
8
|
+
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
|
9
|
+
angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/day.html","template/datepicker/month.html","template/datepicker/popup.html","template/datepicker/year.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]);
|
10
10
|
angular.module('ui.bootstrap.transition', [])
|
11
11
|
|
12
12
|
/**
|
@@ -23,7 +23,7 @@ angular.module('ui.bootstrap.transition', [])
|
|
23
23
|
var $transition = function(element, trigger, options) {
|
24
24
|
options = options || {};
|
25
25
|
var deferred = $q.defer();
|
26
|
-
var endEventName = $transition[options.animation ?
|
26
|
+
var endEventName = $transition[options.animation ? 'animationEndEventName' : 'transitionEndEventName'];
|
27
27
|
|
28
28
|
var transitionEndHandler = function(event) {
|
29
29
|
$rootScope.$apply(function() {
|
@@ -92,7 +92,7 @@ angular.module('ui.bootstrap.transition', [])
|
|
92
92
|
|
93
93
|
angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition'])
|
94
94
|
|
95
|
-
.directive('collapse', ['$transition', function ($transition
|
95
|
+
.directive('collapse', ['$transition', function ($transition) {
|
96
96
|
|
97
97
|
return {
|
98
98
|
link: function (scope, element, attrs) {
|
@@ -188,7 +188,7 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
188
188
|
});
|
189
189
|
}
|
190
190
|
};
|
191
|
-
|
191
|
+
|
192
192
|
// This is called from the accordion-group directive to add itself to the accordion
|
193
193
|
this.addGroup = function(groupScope) {
|
194
194
|
var that = this;
|
@@ -203,7 +203,7 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
203
203
|
this.removeGroup = function(group) {
|
204
204
|
var index = this.groups.indexOf(group);
|
205
205
|
if ( index !== -1 ) {
|
206
|
-
this.groups.splice(
|
206
|
+
this.groups.splice(index, 1);
|
207
207
|
}
|
208
208
|
};
|
209
209
|
|
@@ -222,46 +222,40 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
222
222
|
})
|
223
223
|
|
224
224
|
// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
|
225
|
-
.directive('accordionGroup',
|
225
|
+
.directive('accordionGroup', function() {
|
226
226
|
return {
|
227
227
|
require:'^accordion', // We need this directive to be inside an accordion
|
228
228
|
restrict:'EA',
|
229
229
|
transclude:true, // It transcludes the contents of the directive into the template
|
230
230
|
replace: true, // The element containing the directive will be replaced with the template
|
231
231
|
templateUrl:'template/accordion/accordion-group.html',
|
232
|
-
scope:{
|
232
|
+
scope: {
|
233
|
+
heading: '@', // Interpolate the heading attribute onto this scope
|
234
|
+
isOpen: '=?',
|
235
|
+
isDisabled: '=?'
|
236
|
+
},
|
233
237
|
controller: function() {
|
234
238
|
this.setHeading = function(element) {
|
235
239
|
this.heading = element;
|
236
240
|
};
|
237
241
|
},
|
238
242
|
link: function(scope, element, attrs, accordionCtrl) {
|
239
|
-
var getIsOpen, setIsOpen;
|
240
|
-
|
241
243
|
accordionCtrl.addGroup(scope);
|
242
244
|
|
243
|
-
scope.isOpen = false;
|
244
|
-
|
245
|
-
if ( attrs.isOpen ) {
|
246
|
-
getIsOpen = $parse(attrs.isOpen);
|
247
|
-
setIsOpen = getIsOpen.assign;
|
248
|
-
|
249
|
-
scope.$parent.$watch(getIsOpen, function(value) {
|
250
|
-
scope.isOpen = !!value;
|
251
|
-
});
|
252
|
-
}
|
253
|
-
|
254
245
|
scope.$watch('isOpen', function(value) {
|
255
246
|
if ( value ) {
|
256
247
|
accordionCtrl.closeOthers(scope);
|
257
248
|
}
|
258
|
-
if ( setIsOpen ) {
|
259
|
-
setIsOpen(scope.$parent, value);
|
260
|
-
}
|
261
249
|
});
|
250
|
+
|
251
|
+
scope.toggleOpen = function() {
|
252
|
+
if ( !scope.isDisabled ) {
|
253
|
+
scope.isOpen = !scope.isOpen;
|
254
|
+
}
|
255
|
+
};
|
262
256
|
}
|
263
257
|
};
|
264
|
-
}
|
258
|
+
})
|
265
259
|
|
266
260
|
// Use accordion-heading below an accordion-group to provide a heading containing HTML
|
267
261
|
// <accordion-group>
|
@@ -274,13 +268,11 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
274
268
|
template: '', // In effect remove this element!
|
275
269
|
replace: true,
|
276
270
|
require: '^accordionGroup',
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
accordionGroupCtrl.setHeading(transclude(scope, function() {}));
|
283
|
-
};
|
271
|
+
link: function(scope, element, attr, accordionGroupCtrl, transclude) {
|
272
|
+
// Pass the heading to the accordion-group controller
|
273
|
+
// so that it can be transcluded into the right place in the template
|
274
|
+
// [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
|
275
|
+
accordionGroupCtrl.setHeading(transclude(scope, function() {}));
|
284
276
|
}
|
285
277
|
};
|
286
278
|
})
|
@@ -305,7 +297,7 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
305
297
|
};
|
306
298
|
});
|
307
299
|
|
308
|
-
angular.module(
|
300
|
+
angular.module('ui.bootstrap.alert', [])
|
309
301
|
|
310
302
|
.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
|
311
303
|
$scope.closeable = 'close' in $attrs;
|
@@ -319,7 +311,7 @@ angular.module("ui.bootstrap.alert", [])
|
|
319
311
|
transclude:true,
|
320
312
|
replace:true,
|
321
313
|
scope: {
|
322
|
-
type: '
|
314
|
+
type: '@',
|
323
315
|
close: '&'
|
324
316
|
}
|
325
317
|
};
|
@@ -361,9 +353,11 @@ angular.module('ui.bootstrap.buttons', [])
|
|
361
353
|
|
362
354
|
//ui->model
|
363
355
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
364
|
-
|
356
|
+
var isActive = element.hasClass(buttonsCtrl.activeClass);
|
357
|
+
|
358
|
+
if (!isActive || angular.isDefined(attrs.uncheckable)) {
|
365
359
|
scope.$apply(function () {
|
366
|
-
ngModelCtrl.$setViewValue(scope.$eval(attrs.btnRadio));
|
360
|
+
ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.btnRadio));
|
367
361
|
ngModelCtrl.$render();
|
368
362
|
});
|
369
363
|
}
|
@@ -386,7 +380,7 @@ angular.module('ui.bootstrap.buttons', [])
|
|
386
380
|
function getFalseValue() {
|
387
381
|
return getCheckboxValue(attrs.btnCheckboxFalse, false);
|
388
382
|
}
|
389
|
-
|
383
|
+
|
390
384
|
function getCheckboxValue(attributeValue, defaultValue) {
|
391
385
|
var val = scope.$eval(attributeValue);
|
392
386
|
return angular.isDefined(val) ? val : defaultValue;
|
@@ -417,20 +411,20 @@ angular.module('ui.bootstrap.buttons', [])
|
|
417
411
|
*
|
418
412
|
*/
|
419
413
|
angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
420
|
-
.controller('CarouselController', ['$scope', '$timeout', '$transition',
|
414
|
+
.controller('CarouselController', ['$scope', '$timeout', '$transition', function ($scope, $timeout, $transition) {
|
421
415
|
var self = this,
|
422
|
-
slides = self.slides = [],
|
416
|
+
slides = self.slides = $scope.slides = [],
|
423
417
|
currentIndex = -1,
|
424
418
|
currentTimeout, isPlaying;
|
425
419
|
self.currentSlide = null;
|
426
420
|
|
427
421
|
var destroyed = false;
|
428
422
|
/* direction: "prev" or "next" */
|
429
|
-
self.select = function(nextSlide, direction) {
|
423
|
+
self.select = $scope.select = function(nextSlide, direction) {
|
430
424
|
var nextIndex = slides.indexOf(nextSlide);
|
431
425
|
//Decide direction if it's not given
|
432
426
|
if (direction === undefined) {
|
433
|
-
direction = nextIndex > currentIndex ?
|
427
|
+
direction = nextIndex > currentIndex ? 'next' : 'prev';
|
434
428
|
}
|
435
429
|
if (nextSlide && nextSlide !== self.currentSlide) {
|
436
430
|
if ($scope.$currentTransition) {
|
@@ -506,18 +500,10 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
506
500
|
}
|
507
501
|
};
|
508
502
|
|
509
|
-
$scope.select = function(slide) {
|
510
|
-
self.select(slide);
|
511
|
-
};
|
512
|
-
|
513
503
|
$scope.isActive = function(slide) {
|
514
504
|
return self.currentSlide === slide;
|
515
505
|
};
|
516
506
|
|
517
|
-
$scope.slides = function() {
|
518
|
-
return slides;
|
519
|
-
};
|
520
|
-
|
521
507
|
$scope.$watch('interval', restartTimer);
|
522
508
|
$scope.$on('$destroy', resetTimer);
|
523
509
|
|
@@ -666,36 +652,13 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
666
652
|
</div>
|
667
653
|
</slide>
|
668
654
|
</carousel>
|
669
|
-
<
|
670
|
-
|
671
|
-
<ul>
|
672
|
-
<li ng-repeat="slide in slides">
|
673
|
-
<button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button>
|
674
|
-
{{$index}}: {{slide.text}}
|
675
|
-
</li>
|
676
|
-
</ul>
|
677
|
-
<a class="btn" ng-click="addSlide()">Add Slide</a>
|
678
|
-
</div>
|
679
|
-
<div class="span6">
|
680
|
-
Interval, in milliseconds: <input type="number" ng-model="myInterval">
|
681
|
-
<br />Enter a negative number to stop the interval.
|
682
|
-
</div>
|
683
|
-
</div>
|
655
|
+
Interval, in milliseconds: <input type="number" ng-model="myInterval">
|
656
|
+
<br />Enter a negative number to stop the interval.
|
684
657
|
</div>
|
685
658
|
</file>
|
686
659
|
<file name="script.js">
|
687
660
|
function CarouselDemoCtrl($scope) {
|
688
661
|
$scope.myInterval = 5000;
|
689
|
-
var slides = $scope.slides = [];
|
690
|
-
$scope.addSlide = function() {
|
691
|
-
var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
|
692
|
-
slides.push({
|
693
|
-
image: 'http://placekitten.com/' + newWidth + '/200',
|
694
|
-
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
|
695
|
-
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
|
696
|
-
});
|
697
|
-
};
|
698
|
-
for (var i=0; i<4; i++) $scope.addSlide();
|
699
662
|
}
|
700
663
|
</file>
|
701
664
|
<file name="demo.css">
|
@@ -707,7 +670,7 @@ function CarouselDemoCtrl($scope) {
|
|
707
670
|
</example>
|
708
671
|
*/
|
709
672
|
|
710
|
-
.directive('slide',
|
673
|
+
.directive('slide', function() {
|
711
674
|
return {
|
712
675
|
require: '^carousel',
|
713
676
|
restrict: 'EA',
|
@@ -715,30 +678,9 @@ function CarouselDemoCtrl($scope) {
|
|
715
678
|
replace: true,
|
716
679
|
templateUrl: 'template/carousel/slide.html',
|
717
680
|
scope: {
|
681
|
+
active: '=?'
|
718
682
|
},
|
719
683
|
link: function (scope, element, attrs, carouselCtrl) {
|
720
|
-
//Set up optional 'active' = binding
|
721
|
-
if (attrs.active) {
|
722
|
-
var getActive = $parse(attrs.active);
|
723
|
-
var setActive = getActive.assign;
|
724
|
-
var lastValue = scope.active = getActive(scope.$parent);
|
725
|
-
scope.$watch(function parentActiveWatch() {
|
726
|
-
var parentActive = getActive(scope.$parent);
|
727
|
-
|
728
|
-
if (parentActive !== scope.active) {
|
729
|
-
// we are out of sync and need to copy
|
730
|
-
if (parentActive !== lastValue) {
|
731
|
-
// parent changed and it has precedence
|
732
|
-
lastValue = scope.active = parentActive;
|
733
|
-
} else {
|
734
|
-
// if the parent can be assigned then do so
|
735
|
-
setActive(scope.$parent, parentActive = lastValue = scope.active);
|
736
|
-
}
|
737
|
-
}
|
738
|
-
return parentActive;
|
739
|
-
});
|
740
|
-
}
|
741
|
-
|
742
684
|
carouselCtrl.addSlide(scope, element);
|
743
685
|
//when the scope is destroyed then remove the slide from the current slides array
|
744
686
|
scope.$on('$destroy', function() {
|
@@ -752,6 +694,133 @@ function CarouselDemoCtrl($scope) {
|
|
752
694
|
});
|
753
695
|
}
|
754
696
|
};
|
697
|
+
});
|
698
|
+
|
699
|
+
angular.module('ui.bootstrap.dateparser', [])
|
700
|
+
|
701
|
+
.service('dateParser', ['$locale', 'orderByFilter', function($locale, orderByFilter) {
|
702
|
+
|
703
|
+
this.parsers = {};
|
704
|
+
|
705
|
+
var formatCodeToRegex = {
|
706
|
+
'yyyy': {
|
707
|
+
regex: '\\d{4}',
|
708
|
+
apply: function(value) { this.year = +value; }
|
709
|
+
},
|
710
|
+
'yy': {
|
711
|
+
regex: '\\d{2}',
|
712
|
+
apply: function(value) { this.year = +value + 2000; }
|
713
|
+
},
|
714
|
+
'y': {
|
715
|
+
regex: '\\d{1,4}',
|
716
|
+
apply: function(value) { this.year = +value; }
|
717
|
+
},
|
718
|
+
'MMMM': {
|
719
|
+
regex: $locale.DATETIME_FORMATS.MONTH.join('|'),
|
720
|
+
apply: function(value) { this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value); }
|
721
|
+
},
|
722
|
+
'MMM': {
|
723
|
+
regex: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),
|
724
|
+
apply: function(value) { this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value); }
|
725
|
+
},
|
726
|
+
'MM': {
|
727
|
+
regex: '0[1-9]|1[0-2]',
|
728
|
+
apply: function(value) { this.month = value - 1; }
|
729
|
+
},
|
730
|
+
'M': {
|
731
|
+
regex: '[1-9]|1[0-2]',
|
732
|
+
apply: function(value) { this.month = value - 1; }
|
733
|
+
},
|
734
|
+
'dd': {
|
735
|
+
regex: '[0-2][0-9]{1}|3[0-1]{1}',
|
736
|
+
apply: function(value) { this.date = +value; }
|
737
|
+
},
|
738
|
+
'd': {
|
739
|
+
regex: '[1-2]?[0-9]{1}|3[0-1]{1}',
|
740
|
+
apply: function(value) { this.date = +value; }
|
741
|
+
},
|
742
|
+
'EEEE': {
|
743
|
+
regex: $locale.DATETIME_FORMATS.DAY.join('|')
|
744
|
+
},
|
745
|
+
'EEE': {
|
746
|
+
regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|')
|
747
|
+
}
|
748
|
+
};
|
749
|
+
|
750
|
+
this.createParser = function(format) {
|
751
|
+
var map = [], regex = format.split('');
|
752
|
+
|
753
|
+
angular.forEach(formatCodeToRegex, function(data, code) {
|
754
|
+
var index = format.indexOf(code);
|
755
|
+
|
756
|
+
if (index > -1) {
|
757
|
+
format = format.split('');
|
758
|
+
|
759
|
+
regex[index] = '(' + data.regex + ')';
|
760
|
+
format[index] = '$'; // Custom symbol to define consumed part of format
|
761
|
+
for (var i = index + 1, n = index + code.length; i < n; i++) {
|
762
|
+
regex[i] = '';
|
763
|
+
format[i] = '$';
|
764
|
+
}
|
765
|
+
format = format.join('');
|
766
|
+
|
767
|
+
map.push({ index: index, apply: data.apply });
|
768
|
+
}
|
769
|
+
});
|
770
|
+
|
771
|
+
return {
|
772
|
+
regex: new RegExp('^' + regex.join('') + '$'),
|
773
|
+
map: orderByFilter(map, 'index')
|
774
|
+
};
|
775
|
+
};
|
776
|
+
|
777
|
+
this.parse = function(input, format) {
|
778
|
+
if ( !angular.isString(input) ) {
|
779
|
+
return input;
|
780
|
+
}
|
781
|
+
|
782
|
+
format = $locale.DATETIME_FORMATS[format] || format;
|
783
|
+
|
784
|
+
if ( !this.parsers[format] ) {
|
785
|
+
this.parsers[format] = this.createParser(format);
|
786
|
+
}
|
787
|
+
|
788
|
+
var parser = this.parsers[format],
|
789
|
+
regex = parser.regex,
|
790
|
+
map = parser.map,
|
791
|
+
results = input.match(regex);
|
792
|
+
|
793
|
+
if ( results && results.length ) {
|
794
|
+
var fields = { year: 1900, month: 0, date: 1, hours: 0 }, dt;
|
795
|
+
|
796
|
+
for( var i = 1, n = results.length; i < n; i++ ) {
|
797
|
+
var mapper = map[i-1];
|
798
|
+
if ( mapper.apply ) {
|
799
|
+
mapper.apply.call(fields, results[i]);
|
800
|
+
}
|
801
|
+
}
|
802
|
+
|
803
|
+
if ( isValid(fields.year, fields.month, fields.date) ) {
|
804
|
+
dt = new Date( fields.year, fields.month, fields.date, fields.hours);
|
805
|
+
}
|
806
|
+
|
807
|
+
return dt;
|
808
|
+
}
|
809
|
+
};
|
810
|
+
|
811
|
+
// Check if date is valid for specific month (and year for February).
|
812
|
+
// Month: 0 = Jan, 1 = Feb, etc
|
813
|
+
function isValid(year, month, date) {
|
814
|
+
if ( month === 1 && date > 28) {
|
815
|
+
return date === 29 && ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
|
816
|
+
}
|
817
|
+
|
818
|
+
if ( month === 3 || month === 5 || month === 8 || month === 10) {
|
819
|
+
return date < 31;
|
820
|
+
}
|
821
|
+
|
822
|
+
return true;
|
823
|
+
}
|
755
824
|
}]);
|
756
825
|
|
757
826
|
angular.module('ui.bootstrap.position', [])
|
@@ -779,7 +848,7 @@ angular.module('ui.bootstrap.position', [])
|
|
779
848
|
* @param element - raw DOM element
|
780
849
|
*/
|
781
850
|
function isStaticPositioned(element) {
|
782
|
-
return (getStyle(element,
|
851
|
+
return (getStyle(element, 'position') || 'static' ) === 'static';
|
783
852
|
}
|
784
853
|
|
785
854
|
/**
|
@@ -828,22 +897,97 @@ angular.module('ui.bootstrap.position', [])
|
|
828
897
|
return {
|
829
898
|
width: boundingClientRect.width || element.prop('offsetWidth'),
|
830
899
|
height: boundingClientRect.height || element.prop('offsetHeight'),
|
831
|
-
top: boundingClientRect.top + ($window.pageYOffset || $document[0].
|
832
|
-
left: boundingClientRect.left + ($window.pageXOffset || $document[0].
|
900
|
+
top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),
|
901
|
+
left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)
|
833
902
|
};
|
903
|
+
},
|
904
|
+
|
905
|
+
/**
|
906
|
+
* Provides coordinates for the targetEl in relation to hostEl
|
907
|
+
*/
|
908
|
+
positionElements: function (hostEl, targetEl, positionStr, appendToBody) {
|
909
|
+
|
910
|
+
var positionStrParts = positionStr.split('-');
|
911
|
+
var pos0 = positionStrParts[0], pos1 = positionStrParts[1] || 'center';
|
912
|
+
|
913
|
+
var hostElPos,
|
914
|
+
targetElWidth,
|
915
|
+
targetElHeight,
|
916
|
+
targetElPos;
|
917
|
+
|
918
|
+
hostElPos = appendToBody ? this.offset(hostEl) : this.position(hostEl);
|
919
|
+
|
920
|
+
targetElWidth = targetEl.prop('offsetWidth');
|
921
|
+
targetElHeight = targetEl.prop('offsetHeight');
|
922
|
+
|
923
|
+
var shiftWidth = {
|
924
|
+
center: function () {
|
925
|
+
return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2;
|
926
|
+
},
|
927
|
+
left: function () {
|
928
|
+
return hostElPos.left;
|
929
|
+
},
|
930
|
+
right: function () {
|
931
|
+
return hostElPos.left + hostElPos.width;
|
932
|
+
}
|
933
|
+
};
|
934
|
+
|
935
|
+
var shiftHeight = {
|
936
|
+
center: function () {
|
937
|
+
return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2;
|
938
|
+
},
|
939
|
+
top: function () {
|
940
|
+
return hostElPos.top;
|
941
|
+
},
|
942
|
+
bottom: function () {
|
943
|
+
return hostElPos.top + hostElPos.height;
|
944
|
+
}
|
945
|
+
};
|
946
|
+
|
947
|
+
switch (pos0) {
|
948
|
+
case 'right':
|
949
|
+
targetElPos = {
|
950
|
+
top: shiftHeight[pos1](),
|
951
|
+
left: shiftWidth[pos0]()
|
952
|
+
};
|
953
|
+
break;
|
954
|
+
case 'left':
|
955
|
+
targetElPos = {
|
956
|
+
top: shiftHeight[pos1](),
|
957
|
+
left: hostElPos.left - targetElWidth
|
958
|
+
};
|
959
|
+
break;
|
960
|
+
case 'bottom':
|
961
|
+
targetElPos = {
|
962
|
+
top: shiftHeight[pos0](),
|
963
|
+
left: shiftWidth[pos1]()
|
964
|
+
};
|
965
|
+
break;
|
966
|
+
default:
|
967
|
+
targetElPos = {
|
968
|
+
top: hostElPos.top - targetElHeight,
|
969
|
+
left: shiftWidth[pos1]()
|
970
|
+
};
|
971
|
+
break;
|
972
|
+
}
|
973
|
+
|
974
|
+
return targetElPos;
|
834
975
|
}
|
835
976
|
};
|
836
977
|
}]);
|
837
978
|
|
838
|
-
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
979
|
+
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootstrap.position'])
|
839
980
|
|
840
981
|
.constant('datepickerConfig', {
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
982
|
+
formatDay: 'dd',
|
983
|
+
formatMonth: 'MMMM',
|
984
|
+
formatYear: 'yyyy',
|
985
|
+
formatDayHeader: 'EEE',
|
986
|
+
formatDayTitle: 'MMMM yyyy',
|
987
|
+
formatMonthTitle: 'yyyy',
|
988
|
+
datepickerMode: 'day',
|
989
|
+
minMode: 'day',
|
990
|
+
maxMode: 'year',
|
847
991
|
showWeeks: true,
|
848
992
|
startingDay: 0,
|
849
993
|
yearRange: 20,
|
@@ -851,229 +995,256 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
|
851
995
|
maxDate: null
|
852
996
|
})
|
853
997
|
|
854
|
-
.controller('DatepickerController', ['$scope', '$attrs', 'dateFilter', 'datepickerConfig', function($scope, $attrs, dateFilter,
|
855
|
-
var
|
856
|
-
|
857
|
-
month: getValue($attrs.monthFormat, dtConfig.monthFormat),
|
858
|
-
year: getValue($attrs.yearFormat, dtConfig.yearFormat),
|
859
|
-
dayHeader: getValue($attrs.dayHeaderFormat, dtConfig.dayHeaderFormat),
|
860
|
-
dayTitle: getValue($attrs.dayTitleFormat, dtConfig.dayTitleFormat),
|
861
|
-
monthTitle: getValue($attrs.monthTitleFormat, dtConfig.monthTitleFormat)
|
862
|
-
},
|
863
|
-
startingDay = getValue($attrs.startingDay, dtConfig.startingDay),
|
864
|
-
yearRange = getValue($attrs.yearRange, dtConfig.yearRange);
|
865
|
-
|
866
|
-
this.minDate = dtConfig.minDate ? new Date(dtConfig.minDate) : null;
|
867
|
-
this.maxDate = dtConfig.maxDate ? new Date(dtConfig.maxDate) : null;
|
868
|
-
|
869
|
-
function getValue(value, defaultValue) {
|
870
|
-
return angular.isDefined(value) ? $scope.$parent.$eval(value) : defaultValue;
|
871
|
-
}
|
998
|
+
.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$timeout', '$log', 'dateFilter', 'datepickerConfig', function($scope, $attrs, $parse, $interpolate, $timeout, $log, dateFilter, datepickerConfig) {
|
999
|
+
var self = this,
|
1000
|
+
ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl;
|
872
1001
|
|
873
|
-
|
874
|
-
|
875
|
-
}
|
1002
|
+
// Modes chain
|
1003
|
+
this.modes = ['day', 'month', 'year'];
|
876
1004
|
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
1005
|
+
// Configuration attributes
|
1006
|
+
angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle',
|
1007
|
+
'minMode', 'maxMode', 'showWeeks', 'startingDay', 'yearRange'], function( key, index ) {
|
1008
|
+
self[key] = angular.isDefined($attrs[key]) ? (index < 8 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key];
|
1009
|
+
});
|
1010
|
+
|
1011
|
+
// Watchable attributes
|
1012
|
+
angular.forEach(['minDate', 'maxDate'], function( key ) {
|
1013
|
+
if ( $attrs[key] ) {
|
1014
|
+
$scope.$parent.$watch($parse($attrs[key]), function(value) {
|
1015
|
+
self[key] = value ? new Date(value) : null;
|
1016
|
+
self.refreshView();
|
1017
|
+
});
|
1018
|
+
} else {
|
1019
|
+
self[key] = datepickerConfig[key] ? new Date(datepickerConfig[key]) : null;
|
883
1020
|
}
|
884
|
-
|
885
|
-
}
|
1021
|
+
});
|
886
1022
|
|
887
|
-
|
888
|
-
|
889
|
-
|
1023
|
+
$scope.datepickerMode = $scope.datepickerMode || datepickerConfig.datepickerMode;
|
1024
|
+
$scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000);
|
1025
|
+
this.activeDate = angular.isDefined($attrs.initDate) ? $scope.$parent.$eval($attrs.initDate) : new Date();
|
890
1026
|
|
891
|
-
|
892
|
-
{
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
firstDate = new Date(firstDayOfMonth), numDates = 0;
|
1027
|
+
$scope.isActive = function(dateObject) {
|
1028
|
+
if (self.compare(dateObject.date, self.activeDate) === 0) {
|
1029
|
+
$scope.activeDateId = dateObject.uid;
|
1030
|
+
return true;
|
1031
|
+
}
|
1032
|
+
return false;
|
1033
|
+
};
|
899
1034
|
|
900
|
-
|
901
|
-
|
902
|
-
numDates += numDisplayedFromPreviousMonth; // Previous
|
903
|
-
}
|
904
|
-
numDates += getDaysInMonth(year, month + 1); // Current
|
905
|
-
numDates += (7 - numDates % 7) % 7; // Next
|
1035
|
+
this.init = function( ngModelCtrl_ ) {
|
1036
|
+
ngModelCtrl = ngModelCtrl_;
|
906
1037
|
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
}
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
{
|
924
|
-
name: 'month',
|
925
|
-
getVisibleDates: function(date, selected) {
|
926
|
-
var months = new Array(12), year = date.getFullYear();
|
927
|
-
for ( var i = 0; i < 12; i++ ) {
|
928
|
-
var dt = new Date(year, i, 1);
|
929
|
-
months[i] = makeDate(dt, format.month, (selected && selected.getMonth() === i && selected.getFullYear() === year));
|
930
|
-
}
|
931
|
-
return { objects: months, title: dateFilter(date, format.monthTitle) };
|
932
|
-
},
|
933
|
-
compare: function(date1, date2) {
|
934
|
-
return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
|
935
|
-
},
|
936
|
-
split: 3,
|
937
|
-
step: { years: 1 }
|
938
|
-
},
|
939
|
-
{
|
940
|
-
name: 'year',
|
941
|
-
getVisibleDates: function(date, selected) {
|
942
|
-
var years = new Array(yearRange), year = date.getFullYear(), startYear = parseInt((year - 1) / yearRange, 10) * yearRange + 1;
|
943
|
-
for ( var i = 0; i < yearRange; i++ ) {
|
944
|
-
var dt = new Date(startYear + i, 0, 1);
|
945
|
-
years[i] = makeDate(dt, format.year, (selected && selected.getFullYear() === dt.getFullYear()));
|
946
|
-
}
|
947
|
-
return { objects: years, title: [years[0].label, years[yearRange - 1].label].join(' - ') };
|
948
|
-
},
|
949
|
-
compare: function(date1, date2) {
|
950
|
-
return date1.getFullYear() - date2.getFullYear();
|
951
|
-
},
|
952
|
-
split: 5,
|
953
|
-
step: { years: yearRange }
|
1038
|
+
ngModelCtrl.$render = function() {
|
1039
|
+
self.render();
|
1040
|
+
};
|
1041
|
+
};
|
1042
|
+
|
1043
|
+
this.render = function() {
|
1044
|
+
if ( ngModelCtrl.$modelValue ) {
|
1045
|
+
var date = new Date( ngModelCtrl.$modelValue ),
|
1046
|
+
isValid = !isNaN(date);
|
1047
|
+
|
1048
|
+
if ( isValid ) {
|
1049
|
+
this.activeDate = date;
|
1050
|
+
} else {
|
1051
|
+
$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
1052
|
+
}
|
1053
|
+
ngModelCtrl.$setValidity('date', isValid);
|
954
1054
|
}
|
955
|
-
|
1055
|
+
this.refreshView();
|
1056
|
+
};
|
956
1057
|
|
957
|
-
this.
|
958
|
-
|
959
|
-
|
1058
|
+
this.refreshView = function() {
|
1059
|
+
if ( this.element ) {
|
1060
|
+
this._refreshView();
|
1061
|
+
|
1062
|
+
var date = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null;
|
1063
|
+
ngModelCtrl.$setValidity('date-disabled', !date || (this.element && !this.isDisabled(date)));
|
1064
|
+
}
|
1065
|
+
};
|
1066
|
+
|
1067
|
+
this.createDateObject = function(date, format) {
|
1068
|
+
var model = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null;
|
1069
|
+
return {
|
1070
|
+
date: date,
|
1071
|
+
label: dateFilter(date, format),
|
1072
|
+
selected: model && this.compare(date, model) === 0,
|
1073
|
+
disabled: this.isDisabled(date),
|
1074
|
+
current: this.compare(date, new Date()) === 0
|
1075
|
+
};
|
1076
|
+
};
|
1077
|
+
|
1078
|
+
this.isDisabled = function( date ) {
|
1079
|
+
return ((this.minDate && this.compare(date, this.minDate) < 0) || (this.maxDate && this.compare(date, this.maxDate) > 0) || ($attrs.dateDisabled && $scope.dateDisabled({date: date, mode: $scope.datepickerMode})));
|
1080
|
+
};
|
1081
|
+
|
1082
|
+
// Split array into smaller arrays
|
1083
|
+
this.split = function(arr, size) {
|
1084
|
+
var arrays = [];
|
1085
|
+
while (arr.length > 0) {
|
1086
|
+
arrays.push(arr.splice(0, size));
|
1087
|
+
}
|
1088
|
+
return arrays;
|
1089
|
+
};
|
1090
|
+
|
1091
|
+
$scope.select = function( date ) {
|
1092
|
+
if ( $scope.datepickerMode === self.minMode ) {
|
1093
|
+
var dt = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
|
1094
|
+
dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
|
1095
|
+
ngModelCtrl.$setViewValue( dt );
|
1096
|
+
ngModelCtrl.$render();
|
1097
|
+
} else {
|
1098
|
+
self.activeDate = date;
|
1099
|
+
$scope.datepickerMode = self.modes[ self.modes.indexOf( $scope.datepickerMode ) - 1 ];
|
1100
|
+
}
|
1101
|
+
};
|
1102
|
+
|
1103
|
+
$scope.move = function( direction ) {
|
1104
|
+
var year = self.activeDate.getFullYear() + direction * (self.step.years || 0),
|
1105
|
+
month = self.activeDate.getMonth() + direction * (self.step.months || 0);
|
1106
|
+
self.activeDate.setFullYear(year, month, 1);
|
1107
|
+
self.refreshView();
|
1108
|
+
};
|
1109
|
+
|
1110
|
+
$scope.toggleMode = function( direction ) {
|
1111
|
+
direction = direction || 1;
|
1112
|
+
|
1113
|
+
if (($scope.datepickerMode === self.maxMode && direction === 1) || ($scope.datepickerMode === self.minMode && direction === -1)) {
|
1114
|
+
return;
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
$scope.datepickerMode = self.modes[ self.modes.indexOf( $scope.datepickerMode ) + direction ];
|
1118
|
+
};
|
1119
|
+
|
1120
|
+
// Key event mapper
|
1121
|
+
$scope.keys = { 13:'enter', 32:'space', 33:'pageup', 34:'pagedown', 35:'end', 36:'home', 37:'left', 38:'up', 39:'right', 40:'down' };
|
1122
|
+
|
1123
|
+
var focusElement = function() {
|
1124
|
+
$timeout(function() {
|
1125
|
+
self.element[0].focus();
|
1126
|
+
}, 0 , false);
|
1127
|
+
};
|
1128
|
+
|
1129
|
+
// Listen for focus requests from popup directive
|
1130
|
+
$scope.$on('datepicker.focus', focusElement);
|
1131
|
+
|
1132
|
+
$scope.keydown = function( evt ) {
|
1133
|
+
var key = $scope.keys[evt.which];
|
1134
|
+
|
1135
|
+
if ( !key || evt.shiftKey || evt.altKey ) {
|
1136
|
+
return;
|
1137
|
+
}
|
1138
|
+
|
1139
|
+
evt.preventDefault();
|
1140
|
+
evt.stopPropagation();
|
1141
|
+
|
1142
|
+
if (key === 'enter' || key === 'space') {
|
1143
|
+
if ( self.isDisabled(self.activeDate)) {
|
1144
|
+
return; // do nothing
|
1145
|
+
}
|
1146
|
+
$scope.select(self.activeDate);
|
1147
|
+
focusElement();
|
1148
|
+
} else if (evt.ctrlKey && (key === 'up' || key === 'down')) {
|
1149
|
+
$scope.toggleMode(key === 'up' ? 1 : -1);
|
1150
|
+
focusElement();
|
1151
|
+
} else {
|
1152
|
+
self.handleKeyDown(key, evt);
|
1153
|
+
self.refreshView();
|
1154
|
+
}
|
960
1155
|
};
|
961
1156
|
}])
|
962
1157
|
|
963
|
-
.directive( 'datepicker',
|
1158
|
+
.directive( 'datepicker', function () {
|
964
1159
|
return {
|
965
1160
|
restrict: 'EA',
|
966
1161
|
replace: true,
|
967
1162
|
templateUrl: 'template/datepicker/datepicker.html',
|
968
1163
|
scope: {
|
1164
|
+
datepickerMode: '=?',
|
969
1165
|
dateDisabled: '&'
|
970
1166
|
},
|
971
1167
|
require: ['datepicker', '?^ngModel'],
|
972
1168
|
controller: 'DatepickerController',
|
973
1169
|
link: function(scope, element, attrs, ctrls) {
|
974
|
-
var datepickerCtrl = ctrls[0],
|
1170
|
+
var datepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
975
1171
|
|
976
|
-
if (
|
977
|
-
|
1172
|
+
if ( ngModelCtrl ) {
|
1173
|
+
datepickerCtrl.init( ngModelCtrl );
|
978
1174
|
}
|
1175
|
+
}
|
1176
|
+
};
|
1177
|
+
})
|
979
1178
|
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
} else {
|
989
|
-
updateShowWeekNumbers();
|
990
|
-
}
|
1179
|
+
.directive('daypicker', ['dateFilter', function (dateFilter) {
|
1180
|
+
return {
|
1181
|
+
restrict: 'EA',
|
1182
|
+
replace: true,
|
1183
|
+
templateUrl: 'template/datepicker/day.html',
|
1184
|
+
require: '^datepicker',
|
1185
|
+
link: function(scope, element, attrs, ctrl) {
|
1186
|
+
scope.showWeeks = ctrl.showWeeks;
|
991
1187
|
|
992
|
-
|
993
|
-
|
994
|
-
datepickerCtrl.minDate = value ? new Date(value) : null;
|
995
|
-
refill();
|
996
|
-
});
|
997
|
-
}
|
998
|
-
if (attrs.max) {
|
999
|
-
scope.$parent.$watch($parse(attrs.max), function(value) {
|
1000
|
-
datepickerCtrl.maxDate = value ? new Date(value) : null;
|
1001
|
-
refill();
|
1002
|
-
});
|
1003
|
-
}
|
1188
|
+
ctrl.step = { months: 1 };
|
1189
|
+
ctrl.element = element;
|
1004
1190
|
|
1005
|
-
|
1006
|
-
|
1191
|
+
var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
1192
|
+
function getDaysInMonth( year, month ) {
|
1193
|
+
return ((month === 1) && (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0))) ? 29 : DAYS_IN_MONTH[month];
|
1007
1194
|
}
|
1008
1195
|
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
while (
|
1013
|
-
|
1196
|
+
function getDates(startDate, n) {
|
1197
|
+
var dates = new Array(n), current = new Date(startDate), i = 0;
|
1198
|
+
current.setHours(12); // Prevent repeated dates because of timezone bug
|
1199
|
+
while ( i < n ) {
|
1200
|
+
dates[i++] = new Date(current);
|
1201
|
+
current.setDate( current.getDate() + 1 );
|
1014
1202
|
}
|
1015
|
-
return
|
1203
|
+
return dates;
|
1016
1204
|
}
|
1017
1205
|
|
1018
|
-
function
|
1019
|
-
var
|
1206
|
+
ctrl._refreshView = function() {
|
1207
|
+
var year = ctrl.activeDate.getFullYear(),
|
1208
|
+
month = ctrl.activeDate.getMonth(),
|
1209
|
+
firstDayOfMonth = new Date(year, month, 1),
|
1210
|
+
difference = ctrl.startingDay - firstDayOfMonth.getDay(),
|
1211
|
+
numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference,
|
1212
|
+
firstDate = new Date(firstDayOfMonth);
|
1020
1213
|
|
1021
|
-
if (
|
1022
|
-
|
1023
|
-
|
1024
|
-
if ( isNaN(date) ) {
|
1025
|
-
valid = false;
|
1026
|
-
$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
1027
|
-
} else if ( updateSelected ) {
|
1028
|
-
selected = date;
|
1029
|
-
}
|
1214
|
+
if ( numDisplayedFromPreviousMonth > 0 ) {
|
1215
|
+
firstDate.setDate( - numDisplayedFromPreviousMonth + 1 );
|
1030
1216
|
}
|
1031
|
-
ngModel.$setValidity('date', valid);
|
1032
|
-
|
1033
|
-
var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
|
1034
|
-
angular.forEach(data.objects, function(obj) {
|
1035
|
-
obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
|
1036
|
-
});
|
1037
|
-
|
1038
|
-
ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));
|
1039
1217
|
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1218
|
+
// 42 is the number of days on a six-month calendar
|
1219
|
+
var days = getDates(firstDate, 42);
|
1220
|
+
for (var i = 0; i < 42; i ++) {
|
1221
|
+
days[i] = angular.extend(ctrl.createDateObject(days[i], ctrl.formatDay), {
|
1222
|
+
secondary: days[i].getMonth() !== month,
|
1223
|
+
uid: scope.uniqueId + '-' + i
|
1224
|
+
});
|
1225
|
+
}
|
1044
1226
|
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1227
|
+
scope.labels = new Array(7);
|
1228
|
+
for (var j = 0; j < 7; j++) {
|
1229
|
+
scope.labels[j] = {
|
1230
|
+
abbr: dateFilter(days[j].date, ctrl.formatDayHeader),
|
1231
|
+
full: dateFilter(days[j].date, 'EEEE')
|
1232
|
+
};
|
1233
|
+
}
|
1050
1234
|
|
1051
|
-
|
1052
|
-
|
1053
|
-
};
|
1235
|
+
scope.title = dateFilter(ctrl.activeDate, ctrl.formatDayTitle);
|
1236
|
+
scope.rows = ctrl.split(days, 7);
|
1054
1237
|
|
1055
|
-
|
1056
|
-
|
1057
|
-
var
|
1058
|
-
|
1059
|
-
|
1060
|
-
refill( true );
|
1061
|
-
} else {
|
1062
|
-
selected = date;
|
1063
|
-
setMode( mode - 1 );
|
1238
|
+
if ( scope.showWeeks ) {
|
1239
|
+
scope.weekNumbers = [];
|
1240
|
+
var weekNumber = getISO8601WeekNumber( scope.rows[0][0].date ),
|
1241
|
+
numWeeks = scope.rows.length;
|
1242
|
+
while( scope.weekNumbers.push(weekNumber++) < numWeeks ) {}
|
1064
1243
|
}
|
1065
1244
|
};
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
selected.setFullYear( selected.getFullYear() + direction * (step.years || 0) );
|
1070
|
-
refill();
|
1071
|
-
};
|
1072
|
-
scope.toggleMode = function() {
|
1073
|
-
setMode( (mode + 1) % datepickerCtrl.modes.length );
|
1074
|
-
};
|
1075
|
-
scope.getWeekNumber = function(row) {
|
1076
|
-
return ( mode === 0 && scope.showWeekNumbers && row.length === 7 ) ? getISO8601WeekNumber(row[0].date) : null;
|
1245
|
+
|
1246
|
+
ctrl.compare = function(date1, date2) {
|
1247
|
+
return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) );
|
1077
1248
|
};
|
1078
1249
|
|
1079
1250
|
function getISO8601WeekNumber(date) {
|
@@ -1084,14 +1255,152 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
|
1084
1255
|
checkDate.setDate(1);
|
1085
1256
|
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
1086
1257
|
}
|
1258
|
+
|
1259
|
+
ctrl.handleKeyDown = function( key, evt ) {
|
1260
|
+
var date = ctrl.activeDate.getDate();
|
1261
|
+
|
1262
|
+
if (key === 'left') {
|
1263
|
+
date = date - 1; // up
|
1264
|
+
} else if (key === 'up') {
|
1265
|
+
date = date - 7; // down
|
1266
|
+
} else if (key === 'right') {
|
1267
|
+
date = date + 1; // down
|
1268
|
+
} else if (key === 'down') {
|
1269
|
+
date = date + 7;
|
1270
|
+
} else if (key === 'pageup' || key === 'pagedown') {
|
1271
|
+
var month = ctrl.activeDate.getMonth() + (key === 'pageup' ? - 1 : 1);
|
1272
|
+
ctrl.activeDate.setMonth(month, 1);
|
1273
|
+
date = Math.min(getDaysInMonth(ctrl.activeDate.getFullYear(), ctrl.activeDate.getMonth()), date);
|
1274
|
+
} else if (key === 'home') {
|
1275
|
+
date = 1;
|
1276
|
+
} else if (key === 'end') {
|
1277
|
+
date = getDaysInMonth(ctrl.activeDate.getFullYear(), ctrl.activeDate.getMonth());
|
1278
|
+
}
|
1279
|
+
ctrl.activeDate.setDate(date);
|
1280
|
+
};
|
1281
|
+
|
1282
|
+
ctrl.refreshView();
|
1283
|
+
}
|
1284
|
+
};
|
1285
|
+
}])
|
1286
|
+
|
1287
|
+
.directive('monthpicker', ['dateFilter', function (dateFilter) {
|
1288
|
+
return {
|
1289
|
+
restrict: 'EA',
|
1290
|
+
replace: true,
|
1291
|
+
templateUrl: 'template/datepicker/month.html',
|
1292
|
+
require: '^datepicker',
|
1293
|
+
link: function(scope, element, attrs, ctrl) {
|
1294
|
+
ctrl.step = { years: 1 };
|
1295
|
+
ctrl.element = element;
|
1296
|
+
|
1297
|
+
ctrl._refreshView = function() {
|
1298
|
+
var months = new Array(12),
|
1299
|
+
year = ctrl.activeDate.getFullYear();
|
1300
|
+
|
1301
|
+
for ( var i = 0; i < 12; i++ ) {
|
1302
|
+
months[i] = angular.extend(ctrl.createDateObject(new Date(year, i, 1), ctrl.formatMonth), {
|
1303
|
+
uid: scope.uniqueId + '-' + i
|
1304
|
+
});
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
scope.title = dateFilter(ctrl.activeDate, ctrl.formatMonthTitle);
|
1308
|
+
scope.rows = ctrl.split(months, 3);
|
1309
|
+
};
|
1310
|
+
|
1311
|
+
ctrl.compare = function(date1, date2) {
|
1312
|
+
return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
|
1313
|
+
};
|
1314
|
+
|
1315
|
+
ctrl.handleKeyDown = function( key, evt ) {
|
1316
|
+
var date = ctrl.activeDate.getMonth();
|
1317
|
+
|
1318
|
+
if (key === 'left') {
|
1319
|
+
date = date - 1; // up
|
1320
|
+
} else if (key === 'up') {
|
1321
|
+
date = date - 3; // down
|
1322
|
+
} else if (key === 'right') {
|
1323
|
+
date = date + 1; // down
|
1324
|
+
} else if (key === 'down') {
|
1325
|
+
date = date + 3;
|
1326
|
+
} else if (key === 'pageup' || key === 'pagedown') {
|
1327
|
+
var year = ctrl.activeDate.getFullYear() + (key === 'pageup' ? - 1 : 1);
|
1328
|
+
ctrl.activeDate.setFullYear(year);
|
1329
|
+
} else if (key === 'home') {
|
1330
|
+
date = 0;
|
1331
|
+
} else if (key === 'end') {
|
1332
|
+
date = 11;
|
1333
|
+
}
|
1334
|
+
ctrl.activeDate.setMonth(date);
|
1335
|
+
};
|
1336
|
+
|
1337
|
+
ctrl.refreshView();
|
1338
|
+
}
|
1339
|
+
};
|
1340
|
+
}])
|
1341
|
+
|
1342
|
+
.directive('yearpicker', ['dateFilter', function (dateFilter) {
|
1343
|
+
return {
|
1344
|
+
restrict: 'EA',
|
1345
|
+
replace: true,
|
1346
|
+
templateUrl: 'template/datepicker/year.html',
|
1347
|
+
require: '^datepicker',
|
1348
|
+
link: function(scope, element, attrs, ctrl) {
|
1349
|
+
var range = ctrl.yearRange;
|
1350
|
+
|
1351
|
+
ctrl.step = { years: range };
|
1352
|
+
ctrl.element = element;
|
1353
|
+
|
1354
|
+
function getStartingYear( year ) {
|
1355
|
+
return parseInt((year - 1) / range, 10) * range + 1;
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
ctrl._refreshView = function() {
|
1359
|
+
var years = new Array(range);
|
1360
|
+
|
1361
|
+
for ( var i = 0, start = getStartingYear(ctrl.activeDate.getFullYear()); i < range; i++ ) {
|
1362
|
+
years[i] = angular.extend(ctrl.createDateObject(new Date(start + i, 0, 1), ctrl.formatYear), {
|
1363
|
+
uid: scope.uniqueId + '-' + i
|
1364
|
+
});
|
1365
|
+
}
|
1366
|
+
|
1367
|
+
scope.title = [years[0].label, years[range - 1].label].join(' - ');
|
1368
|
+
scope.rows = ctrl.split(years, 5);
|
1369
|
+
};
|
1370
|
+
|
1371
|
+
ctrl.compare = function(date1, date2) {
|
1372
|
+
return date1.getFullYear() - date2.getFullYear();
|
1373
|
+
};
|
1374
|
+
|
1375
|
+
ctrl.handleKeyDown = function( key, evt ) {
|
1376
|
+
var date = ctrl.activeDate.getFullYear();
|
1377
|
+
|
1378
|
+
if (key === 'left') {
|
1379
|
+
date = date - 1; // up
|
1380
|
+
} else if (key === 'up') {
|
1381
|
+
date = date - 5; // down
|
1382
|
+
} else if (key === 'right') {
|
1383
|
+
date = date + 1; // down
|
1384
|
+
} else if (key === 'down') {
|
1385
|
+
date = date + 5;
|
1386
|
+
} else if (key === 'pageup' || key === 'pagedown') {
|
1387
|
+
date += (key === 'pageup' ? - 1 : 1) * ctrl.step.years;
|
1388
|
+
} else if (key === 'home') {
|
1389
|
+
date = getStartingYear( ctrl.activeDate.getFullYear() );
|
1390
|
+
} else if (key === 'end') {
|
1391
|
+
date = getStartingYear( ctrl.activeDate.getFullYear() ) + range - 1;
|
1392
|
+
}
|
1393
|
+
ctrl.activeDate.setFullYear(date);
|
1394
|
+
};
|
1395
|
+
|
1396
|
+
ctrl.refreshView();
|
1087
1397
|
}
|
1088
1398
|
};
|
1089
1399
|
}])
|
1090
1400
|
|
1091
1401
|
.constant('datepickerPopupConfig', {
|
1092
|
-
|
1402
|
+
datepickerPopup: 'yyyy-MM-dd',
|
1093
1403
|
currentText: 'Today',
|
1094
|
-
toggleWeeksText: 'Weeks',
|
1095
1404
|
clearText: 'Clear',
|
1096
1405
|
closeText: 'Done',
|
1097
1406
|
closeOnDateSelection: true,
|
@@ -1099,98 +1408,74 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
|
1099
1408
|
showButtonBar: true
|
1100
1409
|
})
|
1101
1410
|
|
1102
|
-
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', '
|
1103
|
-
function ($compile, $parse, $document, $position, dateFilter,
|
1411
|
+
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
|
1412
|
+
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
|
1104
1413
|
return {
|
1105
1414
|
restrict: 'EA',
|
1106
1415
|
require: 'ngModel',
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1416
|
+
scope: {
|
1417
|
+
isOpen: '=?',
|
1418
|
+
currentText: '@',
|
1419
|
+
clearText: '@',
|
1420
|
+
closeText: '@',
|
1421
|
+
dateDisabled: '&'
|
1422
|
+
},
|
1423
|
+
link: function(scope, element, attrs, ngModel) {
|
1424
|
+
var dateFormat,
|
1425
|
+
closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$parent.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
|
1426
|
+
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
|
1112
1427
|
|
1113
|
-
attrs.$
|
1114
|
-
dateFormat = value || datepickerPopupConfig.dateFormat;
|
1115
|
-
ngModel.$render();
|
1116
|
-
});
|
1428
|
+
scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
|
1117
1429
|
|
1118
|
-
scope.
|
1430
|
+
scope.getText = function( key ) {
|
1431
|
+
return scope[key + 'Text'] || datepickerPopupConfig[key + 'Text'];
|
1432
|
+
};
|
1119
1433
|
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1434
|
+
attrs.$observe('datepickerPopup', function(value) {
|
1435
|
+
dateFormat = value || datepickerPopupConfig.datepickerPopup;
|
1436
|
+
ngModel.$render();
|
1123
1437
|
});
|
1124
1438
|
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
});
|
1131
|
-
attrs.$observe('clearText', function(text) {
|
1132
|
-
scope.clearText = angular.isDefined(text) ? text : datepickerPopupConfig.clearText;
|
1133
|
-
});
|
1134
|
-
attrs.$observe('closeText', function(text) {
|
1135
|
-
scope.closeText = angular.isDefined(text) ? text : datepickerPopupConfig.closeText;
|
1439
|
+
// popup element used to display calendar
|
1440
|
+
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
|
1441
|
+
popupEl.attr({
|
1442
|
+
'ng-model': 'date',
|
1443
|
+
'ng-change': 'dateSelection()'
|
1136
1444
|
});
|
1137
1445
|
|
1138
|
-
|
1139
|
-
|
1140
|
-
getIsOpen = $parse(attrs.isOpen);
|
1141
|
-
setIsOpen = getIsOpen.assign;
|
1142
|
-
|
1143
|
-
originalScope.$watch(getIsOpen, function updateOpen(value) {
|
1144
|
-
scope.isOpen = !! value;
|
1145
|
-
});
|
1446
|
+
function cameltoDash( string ){
|
1447
|
+
return string.replace(/([A-Z])/g, function($1) { return '-' + $1.toLowerCase(); });
|
1146
1448
|
}
|
1147
|
-
scope.isOpen = getIsOpen ? getIsOpen(originalScope) : false; // Initial state
|
1148
1449
|
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
}
|
1450
|
+
// datepicker element
|
1451
|
+
var datepickerEl = angular.element(popupEl.children()[0]);
|
1452
|
+
if ( attrs.datepickerOptions ) {
|
1453
|
+
angular.forEach(scope.$parent.$eval(attrs.datepickerOptions), function( value, option ) {
|
1454
|
+
datepickerEl.attr( cameltoDash(option), value );
|
1455
|
+
});
|
1155
1456
|
}
|
1156
1457
|
|
1157
|
-
|
1158
|
-
if (
|
1159
|
-
scope.$
|
1160
|
-
|
1458
|
+
angular.forEach(['minDate', 'maxDate'], function( key ) {
|
1459
|
+
if ( attrs[key] ) {
|
1460
|
+
scope.$parent.$watch($parse(attrs[key]), function(value){
|
1461
|
+
scope[key] = value;
|
1161
1462
|
});
|
1463
|
+
datepickerEl.attr(cameltoDash(key), key);
|
1162
1464
|
}
|
1163
|
-
};
|
1164
|
-
|
1165
|
-
var elementFocusBind = function() {
|
1166
|
-
scope.$apply(function() {
|
1167
|
-
setOpen( true );
|
1168
|
-
});
|
1169
|
-
};
|
1170
|
-
|
1171
|
-
// popup element used to display calendar
|
1172
|
-
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
|
1173
|
-
popupEl.attr({
|
1174
|
-
'ng-model': 'date',
|
1175
|
-
'ng-change': 'dateSelection()'
|
1176
1465
|
});
|
1177
|
-
|
1178
|
-
|
1179
|
-
if (attrs.datepickerOptions) {
|
1180
|
-
datepickerOptions = originalScope.$eval(attrs.datepickerOptions);
|
1181
|
-
datepickerEl.attr(angular.extend({}, datepickerOptions));
|
1466
|
+
if (attrs.dateDisabled) {
|
1467
|
+
datepickerEl.attr('date-disabled', 'dateDisabled({ date: date, mode: mode })');
|
1182
1468
|
}
|
1183
1469
|
|
1184
|
-
// TODO: reverse from dateFilter string to Date object
|
1185
1470
|
function parseDate(viewValue) {
|
1186
1471
|
if (!viewValue) {
|
1187
1472
|
ngModel.$setValidity('date', true);
|
1188
1473
|
return null;
|
1189
|
-
} else if (angular.isDate(viewValue)) {
|
1474
|
+
} else if (angular.isDate(viewValue) && !isNaN(viewValue)) {
|
1190
1475
|
ngModel.$setValidity('date', true);
|
1191
1476
|
return viewValue;
|
1192
1477
|
} else if (angular.isString(viewValue)) {
|
1193
|
-
var date = new Date(viewValue);
|
1478
|
+
var date = dateParser.parse(viewValue, dateFormat) || new Date(viewValue);
|
1194
1479
|
if (isNaN(date)) {
|
1195
1480
|
ngModel.$setValidity('date', false);
|
1196
1481
|
return undefined;
|
@@ -1213,8 +1498,9 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1213
1498
|
ngModel.$setViewValue(scope.date);
|
1214
1499
|
ngModel.$render();
|
1215
1500
|
|
1216
|
-
if (closeOnDateSelection) {
|
1217
|
-
|
1501
|
+
if ( closeOnDateSelection ) {
|
1502
|
+
scope.isOpen = false;
|
1503
|
+
element[0].focus();
|
1218
1504
|
}
|
1219
1505
|
};
|
1220
1506
|
|
@@ -1228,62 +1514,60 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1228
1514
|
ngModel.$render = function() {
|
1229
1515
|
var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
|
1230
1516
|
element.val(date);
|
1231
|
-
scope.date = ngModel.$modelValue;
|
1517
|
+
scope.date = parseDate( ngModel.$modelValue );
|
1232
1518
|
};
|
1233
1519
|
|
1234
|
-
|
1235
|
-
if (
|
1236
|
-
|
1237
|
-
scope
|
1520
|
+
var documentClickBind = function(event) {
|
1521
|
+
if (scope.isOpen && event.target !== element[0]) {
|
1522
|
+
scope.$apply(function() {
|
1523
|
+
scope.isOpen = false;
|
1238
1524
|
});
|
1239
|
-
datepickerEl.attr(datepickerAttribute || scopeProperty, scopeProperty);
|
1240
1525
|
}
|
1241
|
-
}
|
1242
|
-
addWatchableAttribute(attrs.min, 'min');
|
1243
|
-
addWatchableAttribute(attrs.max, 'max');
|
1244
|
-
if (attrs.showWeeks) {
|
1245
|
-
addWatchableAttribute(attrs.showWeeks, 'showWeeks', 'show-weeks');
|
1246
|
-
} else {
|
1247
|
-
scope.showWeeks = 'show-weeks' in datepickerOptions ? datepickerOptions['show-weeks'] : datepickerConfig.showWeeks;
|
1248
|
-
datepickerEl.attr('show-weeks', 'showWeeks');
|
1249
|
-
}
|
1250
|
-
if (attrs.dateDisabled) {
|
1251
|
-
datepickerEl.attr('date-disabled', attrs.dateDisabled);
|
1252
|
-
}
|
1526
|
+
};
|
1253
1527
|
|
1254
|
-
function
|
1255
|
-
scope.
|
1256
|
-
|
1257
|
-
|
1528
|
+
var keydown = function(evt, noApply) {
|
1529
|
+
scope.keydown(evt);
|
1530
|
+
};
|
1531
|
+
element.bind('keydown', keydown);
|
1532
|
+
|
1533
|
+
scope.keydown = function(evt) {
|
1534
|
+
if (evt.which === 27) {
|
1535
|
+
evt.preventDefault();
|
1536
|
+
evt.stopPropagation();
|
1537
|
+
scope.close();
|
1538
|
+
} else if (evt.which === 40 && !scope.isOpen) {
|
1539
|
+
scope.isOpen = true;
|
1540
|
+
}
|
1541
|
+
};
|
1258
1542
|
|
1259
|
-
var documentBindingInitialized = false, elementFocusInitialized = false;
|
1260
1543
|
scope.$watch('isOpen', function(value) {
|
1261
1544
|
if (value) {
|
1262
|
-
|
1545
|
+
scope.$broadcast('datepicker.focus');
|
1546
|
+
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
1547
|
+
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
1548
|
+
|
1263
1549
|
$document.bind('click', documentClickBind);
|
1264
|
-
if(elementFocusInitialized) {
|
1265
|
-
element.unbind('focus', elementFocusBind);
|
1266
|
-
}
|
1267
|
-
element[0].focus();
|
1268
|
-
documentBindingInitialized = true;
|
1269
1550
|
} else {
|
1270
|
-
|
1271
|
-
$document.unbind('click', documentClickBind);
|
1272
|
-
}
|
1273
|
-
element.bind('focus', elementFocusBind);
|
1274
|
-
elementFocusInitialized = true;
|
1275
|
-
}
|
1276
|
-
|
1277
|
-
if ( setIsOpen ) {
|
1278
|
-
setIsOpen(originalScope, value);
|
1551
|
+
$document.unbind('click', documentClickBind);
|
1279
1552
|
}
|
1280
1553
|
});
|
1281
1554
|
|
1282
|
-
scope.
|
1283
|
-
|
1555
|
+
scope.select = function( date ) {
|
1556
|
+
if (date === 'today') {
|
1557
|
+
var today = new Date();
|
1558
|
+
if (angular.isDate(ngModel.$modelValue)) {
|
1559
|
+
date = new Date(ngModel.$modelValue);
|
1560
|
+
date.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());
|
1561
|
+
} else {
|
1562
|
+
date = new Date(today.setHours(0, 0, 0, 0));
|
1563
|
+
}
|
1564
|
+
}
|
1565
|
+
scope.dateSelection( date );
|
1284
1566
|
};
|
1285
|
-
|
1286
|
-
|
1567
|
+
|
1568
|
+
scope.close = function() {
|
1569
|
+
scope.isOpen = false;
|
1570
|
+
element[0].focus();
|
1287
1571
|
};
|
1288
1572
|
|
1289
1573
|
var $popup = $compile(popupEl)(scope);
|
@@ -1292,6 +1576,12 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1292
1576
|
} else {
|
1293
1577
|
element.after($popup);
|
1294
1578
|
}
|
1579
|
+
|
1580
|
+
scope.$on('$destroy', function() {
|
1581
|
+
$popup.remove();
|
1582
|
+
element.unbind('keydown', keydown);
|
1583
|
+
$document.unbind('click', documentClickBind);
|
1584
|
+
});
|
1295
1585
|
}
|
1296
1586
|
};
|
1297
1587
|
}])
|
@@ -1311,58 +1601,160 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1311
1601
|
};
|
1312
1602
|
});
|
1313
1603
|
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1604
|
+
angular.module('ui.bootstrap.dropdown', [])
|
1605
|
+
|
1606
|
+
.constant('dropdownConfig', {
|
1607
|
+
openClass: 'open'
|
1608
|
+
})
|
1609
|
+
|
1610
|
+
.service('dropdownService', ['$document', function($document) {
|
1611
|
+
var openScope = null;
|
1612
|
+
|
1613
|
+
this.open = function( dropdownScope ) {
|
1614
|
+
if ( !openScope ) {
|
1615
|
+
$document.bind('click', closeDropdown);
|
1616
|
+
$document.bind('keydown', escapeKeyBind);
|
1617
|
+
}
|
1327
1618
|
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1619
|
+
if ( openScope && openScope !== dropdownScope ) {
|
1620
|
+
openScope.isOpen = false;
|
1621
|
+
}
|
1622
|
+
|
1623
|
+
openScope = dropdownScope;
|
1624
|
+
};
|
1625
|
+
|
1626
|
+
this.close = function( dropdownScope ) {
|
1627
|
+
if ( openScope === dropdownScope ) {
|
1628
|
+
openScope = null;
|
1629
|
+
$document.unbind('click', closeDropdown);
|
1630
|
+
$document.unbind('keydown', escapeKeyBind);
|
1631
|
+
}
|
1632
|
+
};
|
1633
|
+
|
1634
|
+
var closeDropdown = function( evt ) {
|
1635
|
+
if (evt && evt.isDefaultPrevented()) {
|
1636
|
+
return;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
openScope.$apply(function() {
|
1640
|
+
openScope.isOpen = false;
|
1641
|
+
});
|
1642
|
+
};
|
1643
|
+
|
1644
|
+
var escapeKeyBind = function( evt ) {
|
1645
|
+
if ( evt.which === 27 ) {
|
1646
|
+
openScope.focusToggleElement();
|
1647
|
+
closeDropdown();
|
1648
|
+
}
|
1649
|
+
};
|
1650
|
+
}])
|
1651
|
+
|
1652
|
+
.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) {
|
1653
|
+
var self = this,
|
1654
|
+
scope = $scope.$new(), // create a child scope so we are not polluting original one
|
1655
|
+
openClass = dropdownConfig.openClass,
|
1656
|
+
getIsOpen,
|
1657
|
+
setIsOpen = angular.noop,
|
1658
|
+
toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop;
|
1659
|
+
|
1660
|
+
this.init = function( element ) {
|
1661
|
+
self.$element = element;
|
1662
|
+
|
1663
|
+
if ( $attrs.isOpen ) {
|
1664
|
+
getIsOpen = $parse($attrs.isOpen);
|
1665
|
+
setIsOpen = getIsOpen.assign;
|
1666
|
+
|
1667
|
+
$scope.$watch(getIsOpen, function(value) {
|
1668
|
+
scope.isOpen = !!value;
|
1669
|
+
});
|
1670
|
+
}
|
1671
|
+
};
|
1672
|
+
|
1673
|
+
this.toggle = function( open ) {
|
1674
|
+
return scope.isOpen = arguments.length ? !!open : !scope.isOpen;
|
1675
|
+
};
|
1676
|
+
|
1677
|
+
// Allow other directives to watch status
|
1678
|
+
this.isOpen = function() {
|
1679
|
+
return scope.isOpen;
|
1680
|
+
};
|
1681
|
+
|
1682
|
+
scope.focusToggleElement = function() {
|
1683
|
+
if ( self.toggleElement ) {
|
1684
|
+
self.toggleElement[0].focus();
|
1685
|
+
}
|
1686
|
+
};
|
1687
|
+
|
1688
|
+
scope.$watch('isOpen', function( isOpen, wasOpen ) {
|
1689
|
+
$animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass);
|
1690
|
+
|
1691
|
+
if ( isOpen ) {
|
1692
|
+
scope.focusToggleElement();
|
1693
|
+
dropdownService.open( scope );
|
1694
|
+
} else {
|
1695
|
+
dropdownService.close( scope );
|
1696
|
+
}
|
1697
|
+
|
1698
|
+
setIsOpen($scope, isOpen);
|
1699
|
+
if (angular.isDefined(isOpen) && isOpen !== wasOpen) {
|
1700
|
+
toggleInvoker($scope, { open: !!isOpen });
|
1701
|
+
}
|
1702
|
+
});
|
1703
|
+
|
1704
|
+
$scope.$on('$locationChangeSuccess', function() {
|
1705
|
+
scope.isOpen = false;
|
1706
|
+
});
|
1707
|
+
|
1708
|
+
$scope.$on('$destroy', function() {
|
1709
|
+
scope.$destroy();
|
1710
|
+
});
|
1711
|
+
}])
|
1712
|
+
|
1713
|
+
.directive('dropdown', function() {
|
1331
1714
|
return {
|
1332
1715
|
restrict: 'CA',
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1716
|
+
controller: 'DropdownController',
|
1717
|
+
link: function(scope, element, attrs, dropdownCtrl) {
|
1718
|
+
dropdownCtrl.init( element );
|
1719
|
+
}
|
1720
|
+
};
|
1721
|
+
})
|
1337
1722
|
|
1338
|
-
|
1723
|
+
.directive('dropdownToggle', function() {
|
1724
|
+
return {
|
1725
|
+
restrict: 'CA',
|
1726
|
+
require: '?^dropdown',
|
1727
|
+
link: function(scope, element, attrs, dropdownCtrl) {
|
1728
|
+
if ( !dropdownCtrl ) {
|
1729
|
+
return;
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
dropdownCtrl.toggleElement = element;
|
1339
1733
|
|
1734
|
+
var toggleDropdown = function(event) {
|
1340
1735
|
event.preventDefault();
|
1341
|
-
event.stopPropagation();
|
1342
1736
|
|
1343
|
-
if (
|
1344
|
-
|
1737
|
+
if ( !element.hasClass('disabled') && !attrs.disabled ) {
|
1738
|
+
scope.$apply(function() {
|
1739
|
+
dropdownCtrl.toggle();
|
1740
|
+
});
|
1345
1741
|
}
|
1742
|
+
};
|
1346
1743
|
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
closeMenu = angular.noop;
|
1358
|
-
openElement = null;
|
1359
|
-
};
|
1360
|
-
$document.bind('click', closeMenu);
|
1361
|
-
}
|
1744
|
+
element.bind('click', toggleDropdown);
|
1745
|
+
|
1746
|
+
// WAI-ARIA
|
1747
|
+
element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
|
1748
|
+
scope.$watch(dropdownCtrl.isOpen, function( isOpen ) {
|
1749
|
+
element.attr('aria-expanded', !!isOpen);
|
1750
|
+
});
|
1751
|
+
|
1752
|
+
scope.$on('$destroy', function() {
|
1753
|
+
element.unbind('click', toggleDropdown);
|
1362
1754
|
});
|
1363
1755
|
}
|
1364
1756
|
};
|
1365
|
-
}
|
1757
|
+
});
|
1366
1758
|
|
1367
1759
|
angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
1368
1760
|
|
@@ -1449,9 +1841,12 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1449
1841
|
},
|
1450
1842
|
replace: true,
|
1451
1843
|
transclude: true,
|
1452
|
-
templateUrl:
|
1844
|
+
templateUrl: function(tElement, tAttrs) {
|
1845
|
+
return tAttrs.templateUrl || 'template/modal/window.html';
|
1846
|
+
},
|
1453
1847
|
link: function (scope, element, attrs) {
|
1454
|
-
|
1848
|
+
element.addClass(attrs.windowClass || '');
|
1849
|
+
scope.size = attrs.size;
|
1455
1850
|
|
1456
1851
|
$timeout(function () {
|
1457
1852
|
// trigger CSS transitions
|
@@ -1507,8 +1902,11 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1507
1902
|
openedWindows.remove(modalInstance);
|
1508
1903
|
|
1509
1904
|
//remove window DOM element
|
1510
|
-
removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300,
|
1511
|
-
|
1905
|
+
removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, function() {
|
1906
|
+
modalWindow.modalScope.$destroy();
|
1907
|
+
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
|
1908
|
+
checkRemoveBackdrop();
|
1909
|
+
});
|
1512
1910
|
}
|
1513
1911
|
|
1514
1912
|
function checkRemoveBackdrop() {
|
@@ -1562,8 +1960,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1562
1960
|
if (evt.which === 27) {
|
1563
1961
|
modal = openedWindows.top();
|
1564
1962
|
if (modal && modal.value.keyboard) {
|
1963
|
+
evt.preventDefault();
|
1565
1964
|
$rootScope.$apply(function () {
|
1566
|
-
$modalStack.dismiss(modal.key);
|
1965
|
+
$modalStack.dismiss(modal.key, 'escape key press');
|
1567
1966
|
});
|
1568
1967
|
}
|
1569
1968
|
}
|
@@ -1587,12 +1986,15 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1587
1986
|
backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
|
1588
1987
|
body.append(backdropDomEl);
|
1589
1988
|
}
|
1590
|
-
|
1989
|
+
|
1591
1990
|
var angularDomEl = angular.element('<div modal-window></div>');
|
1592
|
-
angularDomEl.attr(
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1991
|
+
angularDomEl.attr({
|
1992
|
+
'template-url': modal.windowTemplateUrl,
|
1993
|
+
'window-class': modal.windowClass,
|
1994
|
+
'size': modal.size,
|
1995
|
+
'index': openedWindows.length() - 1,
|
1996
|
+
'animate': 'animate'
|
1997
|
+
}).html(modal.content);
|
1596
1998
|
|
1597
1999
|
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
1598
2000
|
openedWindows.top().value.modalDomEl = modalDomEl;
|
@@ -1716,7 +2118,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1716
2118
|
content: tplAndVars[0],
|
1717
2119
|
backdrop: modalOptions.backdrop,
|
1718
2120
|
keyboard: modalOptions.keyboard,
|
1719
|
-
windowClass: modalOptions.windowClass
|
2121
|
+
windowClass: modalOptions.windowClass,
|
2122
|
+
windowTemplateUrl: modalOptions.windowTemplateUrl,
|
2123
|
+
size: modalOptions.size
|
1720
2124
|
});
|
1721
2125
|
|
1722
2126
|
}, function resolveError(reason) {
|
@@ -1741,58 +2145,54 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
1741
2145
|
|
1742
2146
|
angular.module('ui.bootstrap.pagination', [])
|
1743
2147
|
|
1744
|
-
.controller('PaginationController', ['$scope', '$attrs', '$parse',
|
2148
|
+
.controller('PaginationController', ['$scope', '$attrs', '$parse', function ($scope, $attrs, $parse) {
|
1745
2149
|
var self = this,
|
2150
|
+
ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
|
1746
2151
|
setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
|
1747
2152
|
|
1748
|
-
this.init = function(
|
2153
|
+
this.init = function(ngModelCtrl_, config) {
|
2154
|
+
ngModelCtrl = ngModelCtrl_;
|
2155
|
+
this.config = config;
|
2156
|
+
|
2157
|
+
ngModelCtrl.$render = function() {
|
2158
|
+
self.render();
|
2159
|
+
};
|
2160
|
+
|
1749
2161
|
if ($attrs.itemsPerPage) {
|
1750
2162
|
$scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
|
1751
2163
|
self.itemsPerPage = parseInt(value, 10);
|
1752
2164
|
$scope.totalPages = self.calculateTotalPages();
|
1753
2165
|
});
|
1754
2166
|
} else {
|
1755
|
-
this.itemsPerPage =
|
2167
|
+
this.itemsPerPage = config.itemsPerPage;
|
1756
2168
|
}
|
1757
2169
|
};
|
1758
2170
|
|
1759
|
-
this.noPrevious = function() {
|
1760
|
-
return this.page === 1;
|
1761
|
-
};
|
1762
|
-
this.noNext = function() {
|
1763
|
-
return this.page === $scope.totalPages;
|
1764
|
-
};
|
1765
|
-
|
1766
|
-
this.isActive = function(page) {
|
1767
|
-
return this.page === page;
|
1768
|
-
};
|
1769
|
-
|
1770
2171
|
this.calculateTotalPages = function() {
|
1771
2172
|
var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
|
1772
|
-
return Math.max(totalPages || 0, 1);
|
1773
|
-
};
|
1774
|
-
|
1775
|
-
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
|
1776
|
-
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
|
2173
|
+
return Math.max(totalPages || 0, 1);
|
1777
2174
|
};
|
1778
2175
|
|
1779
2176
|
this.render = function() {
|
1780
|
-
|
1781
|
-
if (this.page > 0 && this.page <= $scope.totalPages) {
|
1782
|
-
$scope.pages = this.getPages(this.page, $scope.totalPages);
|
1783
|
-
}
|
2177
|
+
$scope.page = parseInt(ngModelCtrl.$viewValue, 10) || 1;
|
1784
2178
|
};
|
1785
2179
|
|
1786
2180
|
$scope.selectPage = function(page) {
|
1787
|
-
if (
|
1788
|
-
|
1789
|
-
|
2181
|
+
if ( $scope.page !== page && page > 0 && page <= $scope.totalPages) {
|
2182
|
+
ngModelCtrl.$setViewValue(page);
|
2183
|
+
ngModelCtrl.$render();
|
1790
2184
|
}
|
1791
2185
|
};
|
1792
2186
|
|
1793
|
-
$scope
|
1794
|
-
self.
|
1795
|
-
}
|
2187
|
+
$scope.getText = function( key ) {
|
2188
|
+
return $scope[key + 'Text'] || self.config[key + 'Text'];
|
2189
|
+
};
|
2190
|
+
$scope.noPrevious = function() {
|
2191
|
+
return $scope.page === 1;
|
2192
|
+
};
|
2193
|
+
$scope.noNext = function() {
|
2194
|
+
return $scope.page === $scope.totalPages;
|
2195
|
+
};
|
1796
2196
|
|
1797
2197
|
$scope.$watch('totalItems', function() {
|
1798
2198
|
$scope.totalPages = self.calculateTotalPages();
|
@@ -1801,10 +2201,10 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1801
2201
|
$scope.$watch('totalPages', function(value) {
|
1802
2202
|
setNumPages($scope.$parent, value); // Readonly variable
|
1803
2203
|
|
1804
|
-
if (
|
2204
|
+
if ( $scope.page > value ) {
|
1805
2205
|
$scope.selectPage(value);
|
1806
2206
|
} else {
|
1807
|
-
|
2207
|
+
ngModelCtrl.$render();
|
1808
2208
|
}
|
1809
2209
|
});
|
1810
2210
|
}])
|
@@ -1820,30 +2220,34 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1820
2220
|
rotate: true
|
1821
2221
|
})
|
1822
2222
|
|
1823
|
-
.directive('pagination', ['$parse', 'paginationConfig', function($parse,
|
2223
|
+
.directive('pagination', ['$parse', 'paginationConfig', function($parse, paginationConfig) {
|
1824
2224
|
return {
|
1825
2225
|
restrict: 'EA',
|
1826
2226
|
scope: {
|
1827
|
-
page: '=',
|
1828
2227
|
totalItems: '=',
|
1829
|
-
|
2228
|
+
firstText: '@',
|
2229
|
+
previousText: '@',
|
2230
|
+
nextText: '@',
|
2231
|
+
lastText: '@'
|
1830
2232
|
},
|
2233
|
+
require: ['pagination', '?ngModel'],
|
1831
2234
|
controller: 'PaginationController',
|
1832
2235
|
templateUrl: 'template/pagination/pagination.html',
|
1833
2236
|
replace: true,
|
1834
|
-
link: function(scope, element, attrs,
|
2237
|
+
link: function(scope, element, attrs, ctrls) {
|
2238
|
+
var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
2239
|
+
|
2240
|
+
if (!ngModelCtrl) {
|
2241
|
+
return; // do nothing if no ng-model
|
2242
|
+
}
|
1835
2243
|
|
1836
2244
|
// Setup configuration parameters
|
1837
|
-
var maxSize,
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
1842
|
-
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1843
|
-
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
|
1844
|
-
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
|
2245
|
+
var maxSize = angular.isDefined(attrs.maxSize) ? scope.$parent.$eval(attrs.maxSize) : paginationConfig.maxSize,
|
2246
|
+
rotate = angular.isDefined(attrs.rotate) ? scope.$parent.$eval(attrs.rotate) : paginationConfig.rotate;
|
2247
|
+
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks;
|
2248
|
+
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : paginationConfig.directionLinks;
|
1845
2249
|
|
1846
|
-
paginationCtrl.init(
|
2250
|
+
paginationCtrl.init(ngModelCtrl, paginationConfig);
|
1847
2251
|
|
1848
2252
|
if (attrs.maxSize) {
|
1849
2253
|
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
|
@@ -1853,16 +2257,15 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1853
2257
|
}
|
1854
2258
|
|
1855
2259
|
// Create page object used in template
|
1856
|
-
function makePage(number, text, isActive
|
2260
|
+
function makePage(number, text, isActive) {
|
1857
2261
|
return {
|
1858
2262
|
number: number,
|
1859
2263
|
text: text,
|
1860
|
-
active: isActive
|
1861
|
-
disabled: isDisabled
|
2264
|
+
active: isActive
|
1862
2265
|
};
|
1863
2266
|
}
|
1864
2267
|
|
1865
|
-
|
2268
|
+
function getPages(currentPage, totalPages) {
|
1866
2269
|
var pages = [];
|
1867
2270
|
|
1868
2271
|
// Default page limits
|
@@ -1892,42 +2295,32 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1892
2295
|
|
1893
2296
|
// Add page number links
|
1894
2297
|
for (var number = startPage; number <= endPage; number++) {
|
1895
|
-
var page = makePage(number, number,
|
2298
|
+
var page = makePage(number, number, number === currentPage);
|
1896
2299
|
pages.push(page);
|
1897
2300
|
}
|
1898
2301
|
|
1899
2302
|
// Add links to move between page sets
|
1900
2303
|
if ( isMaxSized && ! rotate ) {
|
1901
2304
|
if ( startPage > 1 ) {
|
1902
|
-
var previousPageSet = makePage(startPage - 1, '...', false
|
2305
|
+
var previousPageSet = makePage(startPage - 1, '...', false);
|
1903
2306
|
pages.unshift(previousPageSet);
|
1904
2307
|
}
|
1905
2308
|
|
1906
2309
|
if ( endPage < totalPages ) {
|
1907
|
-
var nextPageSet = makePage(endPage + 1, '...', false
|
2310
|
+
var nextPageSet = makePage(endPage + 1, '...', false);
|
1908
2311
|
pages.push(nextPageSet);
|
1909
2312
|
}
|
1910
2313
|
}
|
1911
2314
|
|
1912
|
-
|
1913
|
-
|
1914
|
-
var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
|
1915
|
-
pages.unshift(previousPage);
|
1916
|
-
|
1917
|
-
var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
|
1918
|
-
pages.push(nextPage);
|
1919
|
-
}
|
1920
|
-
|
1921
|
-
// Add first & last links
|
1922
|
-
if (boundaryLinks) {
|
1923
|
-
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
|
1924
|
-
pages.unshift(firstPage);
|
2315
|
+
return pages;
|
2316
|
+
}
|
1925
2317
|
|
1926
|
-
|
1927
|
-
|
2318
|
+
var originalRender = paginationCtrl.render;
|
2319
|
+
paginationCtrl.render = function() {
|
2320
|
+
originalRender();
|
2321
|
+
if (scope.page > 0 && scope.page <= scope.totalPages) {
|
2322
|
+
scope.pages = getPages(scope.page, scope.totalPages);
|
1928
2323
|
}
|
1929
|
-
|
1930
|
-
return pages;
|
1931
2324
|
};
|
1932
2325
|
}
|
1933
2326
|
};
|
@@ -1940,43 +2333,27 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1940
2333
|
align: true
|
1941
2334
|
})
|
1942
2335
|
|
1943
|
-
.directive('pager', ['pagerConfig', function(
|
2336
|
+
.directive('pager', ['pagerConfig', function(pagerConfig) {
|
1944
2337
|
return {
|
1945
2338
|
restrict: 'EA',
|
1946
2339
|
scope: {
|
1947
|
-
page: '=',
|
1948
2340
|
totalItems: '=',
|
1949
|
-
|
2341
|
+
previousText: '@',
|
2342
|
+
nextText: '@'
|
1950
2343
|
},
|
2344
|
+
require: ['pager', '?ngModel'],
|
1951
2345
|
controller: 'PaginationController',
|
1952
2346
|
templateUrl: 'template/pagination/pager.html',
|
1953
2347
|
replace: true,
|
1954
|
-
link: function(scope, element, attrs,
|
1955
|
-
|
1956
|
-
// Setup configuration parameters
|
1957
|
-
var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
1958
|
-
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1959
|
-
align = paginationCtrl.getAttributeValue(attrs.align, config.align);
|
1960
|
-
|
1961
|
-
paginationCtrl.init(config.itemsPerPage);
|
2348
|
+
link: function(scope, element, attrs, ctrls) {
|
2349
|
+
var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
1962
2350
|
|
1963
|
-
|
1964
|
-
|
1965
|
-
return {
|
1966
|
-
number: number,
|
1967
|
-
text: text,
|
1968
|
-
disabled: isDisabled,
|
1969
|
-
previous: ( align && isPrevious ),
|
1970
|
-
next: ( align && isNext )
|
1971
|
-
};
|
2351
|
+
if (!ngModelCtrl) {
|
2352
|
+
return; // do nothing if no ng-model
|
1972
2353
|
}
|
1973
2354
|
|
1974
|
-
|
1975
|
-
|
1976
|
-
makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
|
1977
|
-
makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
|
1978
|
-
];
|
1979
|
-
};
|
2355
|
+
scope.align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : pagerConfig.align;
|
2356
|
+
paginationCtrl.init(ngModelCtrl, pagerConfig);
|
1980
2357
|
}
|
1981
2358
|
};
|
1982
2359
|
}]);
|
@@ -2009,7 +2386,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2009
2386
|
|
2010
2387
|
// The options specified to the provider globally.
|
2011
2388
|
var globalOptions = {};
|
2012
|
-
|
2389
|
+
|
2013
2390
|
/**
|
2014
2391
|
* `options({})` allows global configuration of all tooltips in the
|
2015
2392
|
* application.
|
@@ -2078,7 +2455,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2078
2455
|
|
2079
2456
|
var startSym = $interpolate.startSymbol();
|
2080
2457
|
var endSym = $interpolate.endSymbol();
|
2081
|
-
var template =
|
2458
|
+
var template =
|
2082
2459
|
'<div '+ directiveName +'-popup '+
|
2083
2460
|
'title="'+startSym+'tt_title'+endSym+'" '+
|
2084
2461
|
'content="'+startSym+'tt_content'+endSym+'" '+
|
@@ -2100,56 +2477,16 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2100
2477
|
var popupTimeout;
|
2101
2478
|
var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
|
2102
2479
|
var triggers = getTriggers( undefined );
|
2103
|
-
var hasRegisteredTriggers = false;
|
2104
2480
|
var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
|
2105
2481
|
|
2106
|
-
var positionTooltip = function (){
|
2107
|
-
var position,
|
2108
|
-
ttWidth,
|
2109
|
-
ttHeight,
|
2110
|
-
ttPosition;
|
2111
|
-
// Get the position of the directive element.
|
2112
|
-
position = appendToBody ? $position.offset( element ) : $position.position( element );
|
2113
|
-
|
2114
|
-
// Get the height and width of the tooltip so we can center it.
|
2115
|
-
ttWidth = tooltip.prop( 'offsetWidth' );
|
2116
|
-
ttHeight = tooltip.prop( 'offsetHeight' );
|
2117
|
-
|
2118
|
-
// Calculate the tooltip's top and left coordinates to center it with
|
2119
|
-
// this directive.
|
2120
|
-
switch ( scope.tt_placement ) {
|
2121
|
-
case 'right':
|
2122
|
-
ttPosition = {
|
2123
|
-
top: position.top + position.height / 2 - ttHeight / 2,
|
2124
|
-
left: position.left + position.width
|
2125
|
-
};
|
2126
|
-
break;
|
2127
|
-
case 'bottom':
|
2128
|
-
ttPosition = {
|
2129
|
-
top: position.top + position.height,
|
2130
|
-
left: position.left + position.width / 2 - ttWidth / 2
|
2131
|
-
};
|
2132
|
-
break;
|
2133
|
-
case 'left':
|
2134
|
-
ttPosition = {
|
2135
|
-
top: position.top + position.height / 2 - ttHeight / 2,
|
2136
|
-
left: position.left - ttWidth
|
2137
|
-
};
|
2138
|
-
break;
|
2139
|
-
default:
|
2140
|
-
ttPosition = {
|
2141
|
-
top: position.top - ttHeight,
|
2142
|
-
left: position.left + position.width / 2 - ttWidth / 2
|
2143
|
-
};
|
2144
|
-
break;
|
2145
|
-
}
|
2482
|
+
var positionTooltip = function () {
|
2146
2483
|
|
2484
|
+
var ttPosition = $position.positionElements(element, tooltip, scope.tt_placement, appendToBody);
|
2147
2485
|
ttPosition.top += 'px';
|
2148
2486
|
ttPosition.left += 'px';
|
2149
2487
|
|
2150
2488
|
// Now set the calculated positioning.
|
2151
2489
|
tooltip.css( ttPosition );
|
2152
|
-
|
2153
2490
|
};
|
2154
2491
|
|
2155
2492
|
// By default, the tooltip is not open.
|
@@ -2170,8 +2507,12 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2170
2507
|
return;
|
2171
2508
|
}
|
2172
2509
|
if ( scope.tt_popupDelay ) {
|
2173
|
-
|
2174
|
-
|
2510
|
+
// Do nothing if the tooltip was already scheduled to pop-up.
|
2511
|
+
// This happens if show is triggered multiple times before any hide is triggered.
|
2512
|
+
if (!popupTimeout) {
|
2513
|
+
popupTimeout = $timeout( show, scope.tt_popupDelay, false );
|
2514
|
+
popupTimeout.then(function(reposition){reposition();});
|
2515
|
+
}
|
2175
2516
|
} else {
|
2176
2517
|
show()();
|
2177
2518
|
}
|
@@ -2186,6 +2527,14 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2186
2527
|
// Show the tooltip popup element.
|
2187
2528
|
function show() {
|
2188
2529
|
|
2530
|
+
popupTimeout = null;
|
2531
|
+
|
2532
|
+
// If there is a pending remove transition, we must cancel it, lest the
|
2533
|
+
// tooltip be mysteriously removed.
|
2534
|
+
if ( transitionTimeout ) {
|
2535
|
+
$timeout.cancel( transitionTimeout );
|
2536
|
+
transitionTimeout = null;
|
2537
|
+
}
|
2189
2538
|
|
2190
2539
|
// Don't show empty tooltips.
|
2191
2540
|
if ( ! scope.tt_content ) {
|
@@ -2194,12 +2543,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2194
2543
|
|
2195
2544
|
createTooltip();
|
2196
2545
|
|
2197
|
-
// If there is a pending remove transition, we must cancel it, lest the
|
2198
|
-
// tooltip be mysteriously removed.
|
2199
|
-
if ( transitionTimeout ) {
|
2200
|
-
$timeout.cancel( transitionTimeout );
|
2201
|
-
}
|
2202
|
-
|
2203
2546
|
// Set the initial positioning.
|
2204
2547
|
tooltip.css({ top: 0, left: 0, display: 'block' });
|
2205
2548
|
|
@@ -2229,12 +2572,15 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2229
2572
|
|
2230
2573
|
//if tooltip is going to be shown after delay, we must cancel this
|
2231
2574
|
$timeout.cancel( popupTimeout );
|
2575
|
+
popupTimeout = null;
|
2232
2576
|
|
2233
2577
|
// And now we remove it from the DOM. However, if we have animation, we
|
2234
2578
|
// need to wait for it to expire beforehand.
|
2235
2579
|
// FIXME: this is a placeholder for a port of the transitions library.
|
2236
2580
|
if ( scope.tt_animation ) {
|
2237
|
-
|
2581
|
+
if (!transitionTimeout) {
|
2582
|
+
transitionTimeout = $timeout(removeTooltip, 500);
|
2583
|
+
}
|
2238
2584
|
} else {
|
2239
2585
|
removeTooltip();
|
2240
2586
|
}
|
@@ -2252,6 +2598,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2252
2598
|
}
|
2253
2599
|
|
2254
2600
|
function removeTooltip() {
|
2601
|
+
transitionTimeout = null;
|
2255
2602
|
if (tooltip) {
|
2256
2603
|
tooltip.remove();
|
2257
2604
|
tooltip = null;
|
@@ -2282,11 +2629,9 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2282
2629
|
scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
|
2283
2630
|
});
|
2284
2631
|
|
2285
|
-
var unregisterTriggers = function() {
|
2286
|
-
|
2287
|
-
|
2288
|
-
element.unbind( triggers.hide, hideTooltipBind );
|
2289
|
-
}
|
2632
|
+
var unregisterTriggers = function () {
|
2633
|
+
element.unbind(triggers.show, showTooltipBind);
|
2634
|
+
element.unbind(triggers.hide, hideTooltipBind);
|
2290
2635
|
};
|
2291
2636
|
|
2292
2637
|
attrs.$observe( prefix+'Trigger', function ( val ) {
|
@@ -2300,8 +2645,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2300
2645
|
element.bind( triggers.show, showTooltipBind );
|
2301
2646
|
element.bind( triggers.hide, hideTooltipBind );
|
2302
2647
|
}
|
2303
|
-
|
2304
|
-
hasRegisteredTriggers = true;
|
2305
2648
|
});
|
2306
2649
|
|
2307
2650
|
var animation = scope.$eval(attrs[prefix + 'Animation']);
|
@@ -2382,57 +2725,39 @@ angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
|
|
2382
2725
|
return $tooltip( 'popover', 'popover', 'click' );
|
2383
2726
|
}]);
|
2384
2727
|
|
2385
|
-
angular.module('ui.bootstrap.progressbar', [
|
2728
|
+
angular.module('ui.bootstrap.progressbar', [])
|
2386
2729
|
|
2387
2730
|
.constant('progressConfig', {
|
2388
2731
|
animate: true,
|
2389
2732
|
max: 100
|
2390
2733
|
})
|
2391
2734
|
|
2392
|
-
.controller('ProgressController', ['$scope', '$attrs', 'progressConfig',
|
2735
|
+
.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', function($scope, $attrs, progressConfig) {
|
2393
2736
|
var self = this,
|
2394
|
-
bars = [],
|
2395
|
-
max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max,
|
2396
2737
|
animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
|
2397
2738
|
|
2739
|
+
this.bars = [];
|
2740
|
+
$scope.max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max;
|
2741
|
+
|
2398
2742
|
this.addBar = function(bar, element) {
|
2399
|
-
|
2400
|
-
|
2401
|
-
oldValue = bars[index].value;
|
2743
|
+
if ( !animate ) {
|
2744
|
+
element.css({'transition': 'none'});
|
2402
2745
|
}
|
2403
|
-
bars.push(bar);
|
2404
2746
|
|
2405
|
-
this.
|
2747
|
+
this.bars.push(bar);
|
2406
2748
|
|
2407
|
-
bar.$watch('value', function(value
|
2408
|
-
|
2409
|
-
self.update(element, value, oldValue);
|
2410
|
-
}
|
2749
|
+
bar.$watch('value', function( value ) {
|
2750
|
+
bar.percent = +(100 * value / $scope.max).toFixed(2);
|
2411
2751
|
});
|
2412
2752
|
|
2413
2753
|
bar.$on('$destroy', function() {
|
2754
|
+
element = null;
|
2414
2755
|
self.removeBar(bar);
|
2415
2756
|
});
|
2416
2757
|
};
|
2417
2758
|
|
2418
|
-
// Update bar element width
|
2419
|
-
this.update = function(element, newValue, oldValue) {
|
2420
|
-
var percent = this.getPercentage(newValue);
|
2421
|
-
|
2422
|
-
if (animate) {
|
2423
|
-
element.css('width', this.getPercentage(oldValue) + '%');
|
2424
|
-
$transition(element, {width: percent + '%'});
|
2425
|
-
} else {
|
2426
|
-
element.css({'transition': 'none', 'width': percent + '%'});
|
2427
|
-
}
|
2428
|
-
};
|
2429
|
-
|
2430
2759
|
this.removeBar = function(bar) {
|
2431
|
-
bars.splice(bars.indexOf(bar), 1);
|
2432
|
-
};
|
2433
|
-
|
2434
|
-
this.getPercentage = function(value) {
|
2435
|
-
return Math.round(100 * value / max);
|
2760
|
+
this.bars.splice(this.bars.indexOf(bar), 1);
|
2436
2761
|
};
|
2437
2762
|
}])
|
2438
2763
|
|
@@ -2444,8 +2769,7 @@ angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
|
|
2444
2769
|
controller: 'ProgressController',
|
2445
2770
|
require: 'progress',
|
2446
2771
|
scope: {},
|
2447
|
-
|
2448
|
-
//templateUrl: 'template/progressbar/progress.html' // Works in AngularJS 1.2
|
2772
|
+
templateUrl: 'template/progressbar/progress.html'
|
2449
2773
|
};
|
2450
2774
|
})
|
2451
2775
|
|
@@ -2490,68 +2814,79 @@ angular.module('ui.bootstrap.rating', [])
|
|
2490
2814
|
stateOff: null
|
2491
2815
|
})
|
2492
2816
|
|
2493
|
-
.controller('RatingController', ['$scope', '$attrs', '
|
2817
|
+
.controller('RatingController', ['$scope', '$attrs', 'ratingConfig', function($scope, $attrs, ratingConfig) {
|
2818
|
+
var ngModelCtrl = { $setViewValue: angular.noop };
|
2494
2819
|
|
2495
|
-
this.
|
2496
|
-
|
2497
|
-
|
2820
|
+
this.init = function(ngModelCtrl_) {
|
2821
|
+
ngModelCtrl = ngModelCtrl_;
|
2822
|
+
ngModelCtrl.$render = this.render;
|
2498
2823
|
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2824
|
+
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
|
2825
|
+
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
|
2826
|
+
|
2827
|
+
var ratingStates = angular.isDefined($attrs.ratingStates) ? $scope.$parent.$eval($attrs.ratingStates) :
|
2828
|
+
new Array( angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max );
|
2829
|
+
$scope.range = this.buildTemplateObjects(ratingStates);
|
2830
|
+
};
|
2504
2831
|
|
2832
|
+
this.buildTemplateObjects = function(states) {
|
2505
2833
|
for (var i = 0, n = states.length; i < n; i++) {
|
2506
|
-
states[i] = angular.extend({ index: i },
|
2834
|
+
states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff }, states[i]);
|
2507
2835
|
}
|
2508
2836
|
return states;
|
2509
2837
|
};
|
2510
2838
|
|
2511
|
-
// Get objects used in template
|
2512
|
-
$scope.range = angular.isDefined($attrs.ratingStates) ? this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));
|
2513
|
-
|
2514
2839
|
$scope.rate = function(value) {
|
2515
|
-
if (
|
2516
|
-
|
2840
|
+
if ( !$scope.readonly && value >= 0 && value <= $scope.range.length ) {
|
2841
|
+
ngModelCtrl.$setViewValue(value);
|
2842
|
+
ngModelCtrl.$render();
|
2517
2843
|
}
|
2518
2844
|
};
|
2519
2845
|
|
2520
2846
|
$scope.enter = function(value) {
|
2521
|
-
if (
|
2522
|
-
$scope.
|
2847
|
+
if ( !$scope.readonly ) {
|
2848
|
+
$scope.value = value;
|
2523
2849
|
}
|
2524
2850
|
$scope.onHover({value: value});
|
2525
2851
|
};
|
2526
2852
|
|
2527
2853
|
$scope.reset = function() {
|
2528
|
-
$scope.
|
2854
|
+
$scope.value = ngModelCtrl.$viewValue;
|
2529
2855
|
$scope.onLeave();
|
2530
2856
|
};
|
2531
2857
|
|
2532
|
-
$scope
|
2533
|
-
|
2534
|
-
|
2858
|
+
$scope.onKeydown = function(evt) {
|
2859
|
+
if (/(37|38|39|40)/.test(evt.which)) {
|
2860
|
+
evt.preventDefault();
|
2861
|
+
evt.stopPropagation();
|
2862
|
+
$scope.rate( $scope.value + (evt.which === 38 || evt.which === 39 ? 1 : -1) );
|
2863
|
+
}
|
2864
|
+
};
|
2535
2865
|
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2539
|
-
$scope.readonly = !!value;
|
2540
|
-
});
|
2541
|
-
}
|
2866
|
+
this.render = function() {
|
2867
|
+
$scope.value = ngModelCtrl.$viewValue;
|
2868
|
+
};
|
2542
2869
|
}])
|
2543
2870
|
|
2544
2871
|
.directive('rating', function() {
|
2545
2872
|
return {
|
2546
2873
|
restrict: 'EA',
|
2874
|
+
require: ['rating', 'ngModel'],
|
2547
2875
|
scope: {
|
2548
|
-
|
2876
|
+
readonly: '=?',
|
2549
2877
|
onHover: '&',
|
2550
2878
|
onLeave: '&'
|
2551
2879
|
},
|
2552
2880
|
controller: 'RatingController',
|
2553
2881
|
templateUrl: 'template/rating/rating.html',
|
2554
|
-
replace: true
|
2882
|
+
replace: true,
|
2883
|
+
link: function(scope, element, attrs, ctrls) {
|
2884
|
+
var ratingCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
2885
|
+
|
2886
|
+
if ( ngModelCtrl ) {
|
2887
|
+
ratingCtrl.init( ngModelCtrl );
|
2888
|
+
}
|
2889
|
+
}
|
2555
2890
|
};
|
2556
2891
|
});
|
2557
2892
|
|
@@ -2569,16 +2904,24 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2569
2904
|
var ctrl = this,
|
2570
2905
|
tabs = ctrl.tabs = $scope.tabs = [];
|
2571
2906
|
|
2572
|
-
ctrl.select = function(
|
2907
|
+
ctrl.select = function(selectedTab) {
|
2573
2908
|
angular.forEach(tabs, function(tab) {
|
2574
|
-
tab.active
|
2909
|
+
if (tab.active && tab !== selectedTab) {
|
2910
|
+
tab.active = false;
|
2911
|
+
tab.onDeselect();
|
2912
|
+
}
|
2575
2913
|
});
|
2576
|
-
|
2914
|
+
selectedTab.active = true;
|
2915
|
+
selectedTab.onSelect();
|
2577
2916
|
};
|
2578
2917
|
|
2579
2918
|
ctrl.addTab = function addTab(tab) {
|
2580
2919
|
tabs.push(tab);
|
2581
|
-
|
2920
|
+
// we can't run the select function on the first tab
|
2921
|
+
// since that would select it twice
|
2922
|
+
if (tabs.length === 1) {
|
2923
|
+
tab.active = true;
|
2924
|
+
} else if (tab.active) {
|
2582
2925
|
ctrl.select(tab);
|
2583
2926
|
}
|
2584
2927
|
};
|
@@ -2630,13 +2973,14 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2630
2973
|
restrict: 'EA',
|
2631
2974
|
transclude: true,
|
2632
2975
|
replace: true,
|
2633
|
-
scope: {
|
2976
|
+
scope: {
|
2977
|
+
type: '@'
|
2978
|
+
},
|
2634
2979
|
controller: 'TabsetController',
|
2635
2980
|
templateUrl: 'template/tabs/tabset.html',
|
2636
2981
|
link: function(scope, element, attrs) {
|
2637
2982
|
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
|
2638
2983
|
scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
|
2639
|
-
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
|
2640
2984
|
}
|
2641
2985
|
};
|
2642
2986
|
})
|
@@ -2729,6 +3073,7 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2729
3073
|
templateUrl: 'template/tabs/tab.html',
|
2730
3074
|
transclude: true,
|
2731
3075
|
scope: {
|
3076
|
+
active: '=?',
|
2732
3077
|
heading: '@',
|
2733
3078
|
onSelect: '&select', //This callback is called in contentHeadingTransclude
|
2734
3079
|
//once it inserts the tab's content into the dom
|
@@ -2739,32 +3084,9 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2739
3084
|
},
|
2740
3085
|
compile: function(elm, attrs, transclude) {
|
2741
3086
|
return function postLink(scope, elm, attrs, tabsetCtrl) {
|
2742
|
-
var getActive, setActive;
|
2743
|
-
if (attrs.active) {
|
2744
|
-
getActive = $parse(attrs.active);
|
2745
|
-
setActive = getActive.assign;
|
2746
|
-
scope.$parent.$watch(getActive, function updateActive(value, oldVal) {
|
2747
|
-
// Avoid re-initializing scope.active as it is already initialized
|
2748
|
-
// below. (watcher is called async during init with value ===
|
2749
|
-
// oldVal)
|
2750
|
-
if (value !== oldVal) {
|
2751
|
-
scope.active = !!value;
|
2752
|
-
}
|
2753
|
-
});
|
2754
|
-
scope.active = getActive(scope.$parent);
|
2755
|
-
} else {
|
2756
|
-
setActive = getActive = angular.noop;
|
2757
|
-
}
|
2758
|
-
|
2759
3087
|
scope.$watch('active', function(active) {
|
2760
|
-
// Note this watcher also initializes and assigns scope.active to the
|
2761
|
-
// attrs.active expression.
|
2762
|
-
setActive(scope.$parent, active);
|
2763
3088
|
if (active) {
|
2764
3089
|
tabsetCtrl.select(scope);
|
2765
|
-
scope.onSelect();
|
2766
|
-
} else {
|
2767
|
-
scope.onDeselect();
|
2768
3090
|
}
|
2769
3091
|
});
|
2770
3092
|
|
@@ -2776,7 +3098,7 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2776
3098
|
}
|
2777
3099
|
|
2778
3100
|
scope.select = function() {
|
2779
|
-
if ( !
|
3101
|
+
if ( !scope.disabled ) {
|
2780
3102
|
scope.active = true;
|
2781
3103
|
}
|
2782
3104
|
};
|
@@ -2786,7 +3108,6 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2786
3108
|
tabsetCtrl.removeTab(scope);
|
2787
3109
|
});
|
2788
3110
|
|
2789
|
-
|
2790
3111
|
//We need to transclude later, once the content container is ready.
|
2791
3112
|
//when this link happens, we're inside a tab heading.
|
2792
3113
|
scope.$transcludeFn = transclude;
|
@@ -2854,228 +3175,249 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2854
3175
|
mousewheel: true
|
2855
3176
|
})
|
2856
3177
|
|
2857
|
-
.
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
replace: true,
|
2862
|
-
scope: {},
|
2863
|
-
templateUrl: 'template/timepicker/timepicker.html',
|
2864
|
-
link: function(scope, element, attrs, ngModel) {
|
2865
|
-
if ( !ngModel ) {
|
2866
|
-
return; // do nothing if no ng-model
|
2867
|
-
}
|
3178
|
+
.controller('TimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'timepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) {
|
3179
|
+
var selected = new Date(),
|
3180
|
+
ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
|
3181
|
+
meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS;
|
2868
3182
|
|
2869
|
-
|
2870
|
-
|
3183
|
+
this.init = function( ngModelCtrl_, inputs ) {
|
3184
|
+
ngModelCtrl = ngModelCtrl_;
|
3185
|
+
ngModelCtrl.$render = this.render;
|
2871
3186
|
|
2872
|
-
|
2873
|
-
|
2874
|
-
scope.$parent.$watch($parse(attrs.hourStep), function(value) {
|
2875
|
-
hourStep = parseInt(value, 10);
|
2876
|
-
});
|
2877
|
-
}
|
3187
|
+
var hoursInputEl = inputs.eq(0),
|
3188
|
+
minutesInputEl = inputs.eq(1);
|
2878
3189
|
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
});
|
2884
|
-
}
|
3190
|
+
var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel;
|
3191
|
+
if ( mousewheel ) {
|
3192
|
+
this.setupMousewheelEvents( hoursInputEl, minutesInputEl );
|
3193
|
+
}
|
2885
3194
|
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
|
2890
|
-
scope.showMeridian = !!value;
|
2891
|
-
|
2892
|
-
if ( ngModel.$error.time ) {
|
2893
|
-
// Evaluate from template
|
2894
|
-
var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
|
2895
|
-
if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
|
2896
|
-
selected.setHours( hours );
|
2897
|
-
refresh();
|
2898
|
-
}
|
2899
|
-
} else {
|
2900
|
-
updateTemplate();
|
2901
|
-
}
|
2902
|
-
});
|
2903
|
-
}
|
3195
|
+
$scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
|
3196
|
+
this.setupInputEvents( hoursInputEl, minutesInputEl );
|
3197
|
+
};
|
2904
3198
|
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2908
|
-
|
2909
|
-
|
2910
|
-
|
2911
|
-
}
|
3199
|
+
var hourStep = timepickerConfig.hourStep;
|
3200
|
+
if ($attrs.hourStep) {
|
3201
|
+
$scope.$parent.$watch($parse($attrs.hourStep), function(value) {
|
3202
|
+
hourStep = parseInt(value, 10);
|
3203
|
+
});
|
3204
|
+
}
|
2912
3205
|
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
3206
|
+
var minuteStep = timepickerConfig.minuteStep;
|
3207
|
+
if ($attrs.minuteStep) {
|
3208
|
+
$scope.$parent.$watch($parse($attrs.minuteStep), function(value) {
|
3209
|
+
minuteStep = parseInt(value, 10);
|
3210
|
+
});
|
3211
|
+
}
|
3212
|
+
|
3213
|
+
// 12H / 24H mode
|
3214
|
+
$scope.showMeridian = timepickerConfig.showMeridian;
|
3215
|
+
if ($attrs.showMeridian) {
|
3216
|
+
$scope.$parent.$watch($parse($attrs.showMeridian), function(value) {
|
3217
|
+
$scope.showMeridian = !!value;
|
3218
|
+
|
3219
|
+
if ( ngModelCtrl.$error.time ) {
|
3220
|
+
// Evaluate from template
|
3221
|
+
var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
|
3222
|
+
if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
|
3223
|
+
selected.setHours( hours );
|
3224
|
+
refresh();
|
2920
3225
|
}
|
2921
|
-
|
3226
|
+
} else {
|
3227
|
+
updateTemplate();
|
2922
3228
|
}
|
3229
|
+
});
|
3230
|
+
}
|
2923
3231
|
|
2924
|
-
|
2925
|
-
|
2926
|
-
|
2927
|
-
|
3232
|
+
// Get $scope.hours in 24H mode if valid
|
3233
|
+
function getHoursFromTemplate ( ) {
|
3234
|
+
var hours = parseInt( $scope.hours, 10 );
|
3235
|
+
var valid = ( $scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
|
3236
|
+
if ( !valid ) {
|
3237
|
+
return undefined;
|
3238
|
+
}
|
2928
3239
|
|
2929
|
-
|
2930
|
-
|
3240
|
+
if ( $scope.showMeridian ) {
|
3241
|
+
if ( hours === 12 ) {
|
3242
|
+
hours = 0;
|
2931
3243
|
}
|
3244
|
+
if ( $scope.meridian === meridians[1] ) {
|
3245
|
+
hours = hours + 12;
|
3246
|
+
}
|
3247
|
+
}
|
3248
|
+
return hours;
|
3249
|
+
}
|
2932
3250
|
|
2933
|
-
|
2934
|
-
|
3251
|
+
function getMinutesFromTemplate() {
|
3252
|
+
var minutes = parseInt($scope.minutes, 10);
|
3253
|
+
return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined;
|
3254
|
+
}
|
2935
3255
|
|
2936
|
-
|
2937
|
-
|
2938
|
-
|
3256
|
+
function pad( value ) {
|
3257
|
+
return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
|
3258
|
+
}
|
2939
3259
|
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
3260
|
+
// Respond on mousewheel spin
|
3261
|
+
this.setupMousewheelEvents = function( hoursInputEl, minutesInputEl ) {
|
3262
|
+
var isScrollingUp = function(e) {
|
3263
|
+
if (e.originalEvent) {
|
3264
|
+
e = e.originalEvent;
|
3265
|
+
}
|
3266
|
+
//pick correct delta variable depending on event
|
3267
|
+
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
|
3268
|
+
return (e.detail || delta > 0);
|
3269
|
+
};
|
2948
3270
|
|
2949
|
-
|
2950
|
-
|
2951
|
-
|
2952
|
-
|
3271
|
+
hoursInputEl.bind('mousewheel wheel', function(e) {
|
3272
|
+
$scope.$apply( (isScrollingUp(e)) ? $scope.incrementHours() : $scope.decrementHours() );
|
3273
|
+
e.preventDefault();
|
3274
|
+
});
|
2953
3275
|
|
2954
|
-
|
2955
|
-
|
2956
|
-
|
2957
|
-
|
2958
|
-
}
|
3276
|
+
minutesInputEl.bind('mousewheel wheel', function(e) {
|
3277
|
+
$scope.$apply( (isScrollingUp(e)) ? $scope.incrementMinutes() : $scope.decrementMinutes() );
|
3278
|
+
e.preventDefault();
|
3279
|
+
});
|
2959
3280
|
|
2960
|
-
|
2961
|
-
if ( ! scope.readonlyInput ) {
|
3281
|
+
};
|
2962
3282
|
|
2963
|
-
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
if (angular.isDefined(invalidMinutes)) {
|
2970
|
-
scope.invalidMinutes = invalidMinutes;
|
2971
|
-
}
|
2972
|
-
};
|
3283
|
+
this.setupInputEvents = function( hoursInputEl, minutesInputEl ) {
|
3284
|
+
if ( $scope.readonlyInput ) {
|
3285
|
+
$scope.updateHours = angular.noop;
|
3286
|
+
$scope.updateMinutes = angular.noop;
|
3287
|
+
return;
|
3288
|
+
}
|
2973
3289
|
|
2974
|
-
|
2975
|
-
|
3290
|
+
var invalidate = function(invalidHours, invalidMinutes) {
|
3291
|
+
ngModelCtrl.$setViewValue( null );
|
3292
|
+
ngModelCtrl.$setValidity('time', false);
|
3293
|
+
if (angular.isDefined(invalidHours)) {
|
3294
|
+
$scope.invalidHours = invalidHours;
|
3295
|
+
}
|
3296
|
+
if (angular.isDefined(invalidMinutes)) {
|
3297
|
+
$scope.invalidMinutes = invalidMinutes;
|
3298
|
+
}
|
3299
|
+
};
|
2976
3300
|
|
2977
|
-
|
2978
|
-
|
2979
|
-
refresh( 'h' );
|
2980
|
-
} else {
|
2981
|
-
invalidate(true);
|
2982
|
-
}
|
2983
|
-
};
|
3301
|
+
$scope.updateHours = function() {
|
3302
|
+
var hours = getHoursFromTemplate();
|
2984
3303
|
|
2985
|
-
|
2986
|
-
|
2987
|
-
|
2988
|
-
|
2989
|
-
|
2990
|
-
|
3304
|
+
if ( angular.isDefined(hours) ) {
|
3305
|
+
selected.setHours( hours );
|
3306
|
+
refresh( 'h' );
|
3307
|
+
} else {
|
3308
|
+
invalidate(true);
|
3309
|
+
}
|
3310
|
+
};
|
3311
|
+
|
3312
|
+
hoursInputEl.bind('blur', function(e) {
|
3313
|
+
if ( !$scope.invalidHours && $scope.hours < 10) {
|
3314
|
+
$scope.$apply( function() {
|
3315
|
+
$scope.hours = pad( $scope.hours );
|
2991
3316
|
});
|
3317
|
+
}
|
3318
|
+
});
|
2992
3319
|
|
2993
|
-
|
2994
|
-
|
3320
|
+
$scope.updateMinutes = function() {
|
3321
|
+
var minutes = getMinutesFromTemplate();
|
2995
3322
|
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
3000
|
-
|
3001
|
-
|
3002
|
-
|
3323
|
+
if ( angular.isDefined(minutes) ) {
|
3324
|
+
selected.setMinutes( minutes );
|
3325
|
+
refresh( 'm' );
|
3326
|
+
} else {
|
3327
|
+
invalidate(undefined, true);
|
3328
|
+
}
|
3329
|
+
};
|
3003
3330
|
|
3004
|
-
|
3005
|
-
|
3006
|
-
|
3007
|
-
|
3008
|
-
});
|
3009
|
-
}
|
3331
|
+
minutesInputEl.bind('blur', function(e) {
|
3332
|
+
if ( !$scope.invalidMinutes && $scope.minutes < 10 ) {
|
3333
|
+
$scope.$apply( function() {
|
3334
|
+
$scope.minutes = pad( $scope.minutes );
|
3010
3335
|
});
|
3011
|
-
} else {
|
3012
|
-
scope.updateHours = angular.noop;
|
3013
|
-
scope.updateMinutes = angular.noop;
|
3014
3336
|
}
|
3337
|
+
});
|
3015
3338
|
|
3016
|
-
|
3017
|
-
var date = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : null;
|
3339
|
+
};
|
3018
3340
|
|
3019
|
-
|
3020
|
-
|
3021
|
-
$log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
3022
|
-
} else {
|
3023
|
-
if ( date ) {
|
3024
|
-
selected = date;
|
3025
|
-
}
|
3026
|
-
makeValid();
|
3027
|
-
updateTemplate();
|
3028
|
-
}
|
3029
|
-
};
|
3341
|
+
this.render = function() {
|
3342
|
+
var date = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : null;
|
3030
3343
|
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
|
3344
|
+
if ( isNaN(date) ) {
|
3345
|
+
ngModelCtrl.$setValidity('time', false);
|
3346
|
+
$log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
3347
|
+
} else {
|
3348
|
+
if ( date ) {
|
3349
|
+
selected = date;
|
3036
3350
|
}
|
3351
|
+
makeValid();
|
3352
|
+
updateTemplate();
|
3353
|
+
}
|
3354
|
+
};
|
3037
3355
|
|
3038
|
-
|
3039
|
-
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3356
|
+
// Call internally when we know that model is valid.
|
3357
|
+
function refresh( keyboardChange ) {
|
3358
|
+
makeValid();
|
3359
|
+
ngModelCtrl.$setViewValue( new Date(selected) );
|
3360
|
+
updateTemplate( keyboardChange );
|
3361
|
+
}
|
3043
3362
|
|
3044
|
-
|
3045
|
-
|
3363
|
+
function makeValid() {
|
3364
|
+
ngModelCtrl.$setValidity('time', true);
|
3365
|
+
$scope.invalidHours = false;
|
3366
|
+
$scope.invalidMinutes = false;
|
3367
|
+
}
|
3046
3368
|
|
3047
|
-
|
3048
|
-
|
3049
|
-
}
|
3050
|
-
scope.hours = keyboardChange === 'h' ? hours : pad(hours);
|
3051
|
-
scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
|
3052
|
-
scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
3053
|
-
}
|
3369
|
+
function updateTemplate( keyboardChange ) {
|
3370
|
+
var hours = selected.getHours(), minutes = selected.getMinutes();
|
3054
3371
|
|
3055
|
-
|
3056
|
-
|
3057
|
-
|
3058
|
-
refresh();
|
3059
|
-
}
|
3372
|
+
if ( $scope.showMeridian ) {
|
3373
|
+
hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system
|
3374
|
+
}
|
3060
3375
|
|
3061
|
-
|
3062
|
-
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
3066
|
-
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
3070
|
-
|
3071
|
-
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
3376
|
+
$scope.hours = keyboardChange === 'h' ? hours : pad(hours);
|
3377
|
+
$scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
|
3378
|
+
$scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
3379
|
+
}
|
3380
|
+
|
3381
|
+
function addMinutes( minutes ) {
|
3382
|
+
var dt = new Date( selected.getTime() + minutes * 60000 );
|
3383
|
+
selected.setHours( dt.getHours(), dt.getMinutes() );
|
3384
|
+
refresh();
|
3385
|
+
}
|
3386
|
+
|
3387
|
+
$scope.incrementHours = function() {
|
3388
|
+
addMinutes( hourStep * 60 );
|
3389
|
+
};
|
3390
|
+
$scope.decrementHours = function() {
|
3391
|
+
addMinutes( - hourStep * 60 );
|
3392
|
+
};
|
3393
|
+
$scope.incrementMinutes = function() {
|
3394
|
+
addMinutes( minuteStep );
|
3395
|
+
};
|
3396
|
+
$scope.decrementMinutes = function() {
|
3397
|
+
addMinutes( - minuteStep );
|
3398
|
+
};
|
3399
|
+
$scope.toggleMeridian = function() {
|
3400
|
+
addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) );
|
3401
|
+
};
|
3402
|
+
}])
|
3403
|
+
|
3404
|
+
.directive('timepicker', function () {
|
3405
|
+
return {
|
3406
|
+
restrict: 'EA',
|
3407
|
+
require: ['timepicker', '?^ngModel'],
|
3408
|
+
controller:'TimepickerController',
|
3409
|
+
replace: true,
|
3410
|
+
scope: {},
|
3411
|
+
templateUrl: 'template/timepicker/timepicker.html',
|
3412
|
+
link: function(scope, element, attrs, ctrls) {
|
3413
|
+
var timepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
3414
|
+
|
3415
|
+
if ( ngModelCtrl ) {
|
3416
|
+
timepickerCtrl.init( ngModelCtrl, element.find('input') );
|
3417
|
+
}
|
3076
3418
|
}
|
3077
3419
|
};
|
3078
|
-
}
|
3420
|
+
});
|
3079
3421
|
|
3080
3422
|
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
|
3081
3423
|
|
@@ -3091,11 +3433,11 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3091
3433
|
return {
|
3092
3434
|
parse:function (input) {
|
3093
3435
|
|
3094
|
-
var match = input.match(TYPEAHEAD_REGEXP)
|
3436
|
+
var match = input.match(TYPEAHEAD_REGEXP);
|
3095
3437
|
if (!match) {
|
3096
3438
|
throw new Error(
|
3097
|
-
|
3098
|
-
|
3439
|
+
'Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_"' +
|
3440
|
+
' but got "' + input + '".');
|
3099
3441
|
}
|
3100
3442
|
|
3101
3443
|
return {
|
@@ -3136,7 +3478,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3136
3478
|
|
3137
3479
|
var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
|
3138
3480
|
|
3139
|
-
var appendToBody = attrs.typeaheadAppendToBody ?
|
3481
|
+
var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false;
|
3140
3482
|
|
3141
3483
|
//INTERNAL VARIABLES
|
3142
3484
|
|
@@ -3148,9 +3490,25 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3148
3490
|
|
3149
3491
|
var hasFocus;
|
3150
3492
|
|
3493
|
+
//create a child scope for the typeahead directive so we are not polluting original scope
|
3494
|
+
//with typeahead-specific data (matches, query etc.)
|
3495
|
+
var scope = originalScope.$new();
|
3496
|
+
originalScope.$on('$destroy', function(){
|
3497
|
+
scope.$destroy();
|
3498
|
+
});
|
3499
|
+
|
3500
|
+
// WAI-ARIA
|
3501
|
+
var popupId = 'typeahead-' + scope.$id + '-' + Math.floor(Math.random() * 10000);
|
3502
|
+
element.attr({
|
3503
|
+
'aria-autocomplete': 'list',
|
3504
|
+
'aria-expanded': false,
|
3505
|
+
'aria-owns': popupId
|
3506
|
+
});
|
3507
|
+
|
3151
3508
|
//pop-up element used to display matches
|
3152
3509
|
var popUpEl = angular.element('<div typeahead-popup></div>');
|
3153
3510
|
popUpEl.attr({
|
3511
|
+
id: popupId,
|
3154
3512
|
matches: 'matches',
|
3155
3513
|
active: 'activeIdx',
|
3156
3514
|
select: 'select(activeIdx)',
|
@@ -3162,18 +3520,26 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3162
3520
|
popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
|
3163
3521
|
}
|
3164
3522
|
|
3165
|
-
//create a child scope for the typeahead directive so we are not polluting original scope
|
3166
|
-
//with typeahead-specific data (matches, query etc.)
|
3167
|
-
var scope = originalScope.$new();
|
3168
|
-
originalScope.$on('$destroy', function(){
|
3169
|
-
scope.$destroy();
|
3170
|
-
});
|
3171
|
-
|
3172
3523
|
var resetMatches = function() {
|
3173
3524
|
scope.matches = [];
|
3174
3525
|
scope.activeIdx = -1;
|
3526
|
+
element.attr('aria-expanded', false);
|
3175
3527
|
};
|
3176
3528
|
|
3529
|
+
var getMatchId = function(index) {
|
3530
|
+
return popupId + '-option-' + index;
|
3531
|
+
};
|
3532
|
+
|
3533
|
+
// Indicate that the specified match is the active (pre-selected) item in the list owned by this typeahead.
|
3534
|
+
// This attribute is added or removed automatically when the `activeIdx` changes.
|
3535
|
+
scope.$watch('activeIdx', function(index) {
|
3536
|
+
if (index < 0) {
|
3537
|
+
element.removeAttr('aria-activedescendant');
|
3538
|
+
} else {
|
3539
|
+
element.attr('aria-activedescendant', getMatchId(index));
|
3540
|
+
}
|
3541
|
+
});
|
3542
|
+
|
3177
3543
|
var getMatchesAsync = function(inputValue) {
|
3178
3544
|
|
3179
3545
|
var locals = {$viewValue: inputValue};
|
@@ -3182,7 +3548,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3182
3548
|
|
3183
3549
|
//it might happen that several async queries were in progress if a user were typing fast
|
3184
3550
|
//but we are interested only in responses that correspond to the current view value
|
3185
|
-
|
3551
|
+
var onCurrentRequest = (inputValue === modelCtrl.$viewValue);
|
3552
|
+
if (onCurrentRequest && hasFocus) {
|
3186
3553
|
if (matches.length > 0) {
|
3187
3554
|
|
3188
3555
|
scope.activeIdx = 0;
|
@@ -3192,6 +3559,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3192
3559
|
for(var i=0; i<matches.length; i++) {
|
3193
3560
|
locals[parserResult.itemName] = matches[i];
|
3194
3561
|
scope.matches.push({
|
3562
|
+
id: getMatchId(i),
|
3195
3563
|
label: parserResult.viewMapper(scope, locals),
|
3196
3564
|
model: matches[i]
|
3197
3565
|
});
|
@@ -3204,9 +3572,12 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3204
3572
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
3205
3573
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
3206
3574
|
|
3575
|
+
element.attr('aria-expanded', true);
|
3207
3576
|
} else {
|
3208
3577
|
resetMatches();
|
3209
3578
|
}
|
3579
|
+
}
|
3580
|
+
if (onCurrentRequest) {
|
3210
3581
|
isLoadingSetter(originalScope, false);
|
3211
3582
|
}
|
3212
3583
|
}, function(){
|
@@ -3300,8 +3671,9 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3300
3671
|
|
3301
3672
|
resetMatches();
|
3302
3673
|
|
3303
|
-
//return focus to the input element if a
|
3304
|
-
|
3674
|
+
//return focus to the input element if a match was selected via a mouse click event
|
3675
|
+
// use timeout to avoid $rootScope:inprog error
|
3676
|
+
$timeout(function() { element[0].focus(); }, 0, false);
|
3305
3677
|
};
|
3306
3678
|
|
3307
3679
|
//bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)
|
@@ -3419,19 +3791,20 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
3419
3791
|
.filter('typeaheadHighlight', function() {
|
3420
3792
|
|
3421
3793
|
function escapeRegexp(queryToEscape) {
|
3422
|
-
return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g,
|
3794
|
+
return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
|
3423
3795
|
}
|
3424
3796
|
|
3425
3797
|
return function(matchItem, query) {
|
3426
|
-
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
|
3798
|
+
return query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
|
3427
3799
|
};
|
3428
3800
|
});
|
3801
|
+
|
3429
3802
|
angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
|
3430
3803
|
$templateCache.put("template/accordion/accordion-group.html",
|
3431
3804
|
"<div class=\"panel panel-default\">\n" +
|
3432
3805
|
" <div class=\"panel-heading\">\n" +
|
3433
3806
|
" <h4 class=\"panel-title\">\n" +
|
3434
|
-
" <a class=\"accordion-toggle\" ng-click=\"
|
3807
|
+
" <a class=\"accordion-toggle\" ng-click=\"toggleOpen()\" accordion-transclude=\"heading\"><span ng-class=\"{'text-muted': isDisabled}\">{{heading}}</span></a>\n" +
|
3435
3808
|
" </h4>\n" +
|
3436
3809
|
" </div>\n" +
|
3437
3810
|
" <div class=\"panel-collapse\" collapse=\"!isOpen\">\n" +
|
@@ -3447,8 +3820,11 @@ angular.module("template/accordion/accordion.html", []).run(["$templateCache", f
|
|
3447
3820
|
|
3448
3821
|
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
|
3449
3822
|
$templateCache.put("template/alert/alert.html",
|
3450
|
-
"<div class
|
3451
|
-
" <button ng-show
|
3823
|
+
"<div class=\"alert\" ng-class=\"{'alert-{{type || 'warning'}}': true, 'alert-dismissable': closeable}\" role=\"alert\">\n" +
|
3824
|
+
" <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close()\">\n" +
|
3825
|
+
" <span aria-hidden=\"true\">×</span>\n" +
|
3826
|
+
" <span class=\"sr-only\">Close</span>\n" +
|
3827
|
+
" </button>\n" +
|
3452
3828
|
" <div ng-transclude></div>\n" +
|
3453
3829
|
"</div>\n" +
|
3454
3830
|
"");
|
@@ -3456,13 +3832,13 @@ angular.module("template/alert/alert.html", []).run(["$templateCache", function(
|
|
3456
3832
|
|
3457
3833
|
angular.module("template/carousel/carousel.html", []).run(["$templateCache", function($templateCache) {
|
3458
3834
|
$templateCache.put("template/carousel/carousel.html",
|
3459
|
-
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\">\n" +
|
3460
|
-
" <ol class=\"carousel-indicators\" ng-show=\"slides
|
3461
|
-
" <li ng-repeat=\"slide in slides
|
3835
|
+
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
|
3836
|
+
" <ol class=\"carousel-indicators\" ng-show=\"slides.length > 1\">\n" +
|
3837
|
+
" <li ng-repeat=\"slide in slides track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\"></li>\n" +
|
3462
3838
|
" </ol>\n" +
|
3463
3839
|
" <div class=\"carousel-inner\" ng-transclude></div>\n" +
|
3464
|
-
" <a class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides
|
3465
|
-
" <a class=\"right carousel-control\" ng-click=\"next()\" ng-show=\"slides
|
3840
|
+
" <a class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides.length > 1\"><span class=\"glyphicon glyphicon-chevron-left\"></span></a>\n" +
|
3841
|
+
" <a class=\"right carousel-control\" ng-click=\"next()\" ng-show=\"slides.length > 1\"><span class=\"glyphicon glyphicon-chevron-right\"></span></a>\n" +
|
3466
3842
|
"</div>\n" +
|
3467
3843
|
"");
|
3468
3844
|
}]);
|
@@ -3481,23 +3857,53 @@ angular.module("template/carousel/slide.html", []).run(["$templateCache", functi
|
|
3481
3857
|
|
3482
3858
|
angular.module("template/datepicker/datepicker.html", []).run(["$templateCache", function($templateCache) {
|
3483
3859
|
$templateCache.put("template/datepicker/datepicker.html",
|
3484
|
-
"<
|
3860
|
+
"<div ng-switch=\"datepickerMode\" role=\"application\" ng-keydown=\"keydown($event)\">\n" +
|
3861
|
+
" <daypicker ng-switch-when=\"day\" tabindex=\"0\"></daypicker>\n" +
|
3862
|
+
" <monthpicker ng-switch-when=\"month\" tabindex=\"0\"></monthpicker>\n" +
|
3863
|
+
" <yearpicker ng-switch-when=\"year\" tabindex=\"0\"></yearpicker>\n" +
|
3864
|
+
"</div>");
|
3865
|
+
}]);
|
3866
|
+
|
3867
|
+
angular.module("template/datepicker/day.html", []).run(["$templateCache", function($templateCache) {
|
3868
|
+
$templateCache.put("template/datepicker/day.html",
|
3869
|
+
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
3485
3870
|
" <thead>\n" +
|
3486
3871
|
" <tr>\n" +
|
3487
|
-
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
|
3488
|
-
" <th colspan=\"{{
|
3489
|
-
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
|
3872
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
|
3873
|
+
" <th colspan=\"{{5 + showWeeks}}\"><button id=\"{{uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"toggleMode()\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
3874
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
|
3875
|
+
" </tr>\n" +
|
3876
|
+
" <tr>\n" +
|
3877
|
+
" <th ng-show=\"showWeeks\" class=\"text-center\"></th>\n" +
|
3878
|
+
" <th ng-repeat=\"label in labels track by $index\" class=\"text-center\"><small aria-label=\"{{label.full}}\">{{label.abbr}}</small></th>\n" +
|
3879
|
+
" </tr>\n" +
|
3880
|
+
" </thead>\n" +
|
3881
|
+
" <tbody>\n" +
|
3882
|
+
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
3883
|
+
" <td ng-show=\"showWeeks\" class=\"text-center h6\"><em>{{ weekNumbers[$index] }}</em></td>\n" +
|
3884
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\" aria-disabled=\"{{!!dt.disabled}}\">\n" +
|
3885
|
+
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'btn-info': dt.selected, active: isActive(dt)}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\" tabindex=\"-1\"><span ng-class=\"{'text-muted': dt.secondary, 'text-info': dt.current}\">{{dt.label}}</span></button>\n" +
|
3886
|
+
" </td>\n" +
|
3490
3887
|
" </tr>\n" +
|
3491
|
-
"
|
3492
|
-
"
|
3493
|
-
"
|
3888
|
+
" </tbody>\n" +
|
3889
|
+
"</table>\n" +
|
3890
|
+
"");
|
3891
|
+
}]);
|
3892
|
+
|
3893
|
+
angular.module("template/datepicker/month.html", []).run(["$templateCache", function($templateCache) {
|
3894
|
+
$templateCache.put("template/datepicker/month.html",
|
3895
|
+
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
3896
|
+
" <thead>\n" +
|
3897
|
+
" <tr>\n" +
|
3898
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
|
3899
|
+
" <th><button id=\"{{uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"toggleMode()\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
3900
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
|
3494
3901
|
" </tr>\n" +
|
3495
3902
|
" </thead>\n" +
|
3496
3903
|
" <tbody>\n" +
|
3497
|
-
" <tr ng-repeat=\"row in rows\">\n" +
|
3498
|
-
" <td ng-
|
3499
|
-
"
|
3500
|
-
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'btn-info': dt.selected}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{'text-muted': dt.secondary}\">{{dt.label}}</span></button>\n" +
|
3904
|
+
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
3905
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\" aria-disabled=\"{{!!dt.disabled}}\">\n" +
|
3906
|
+
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default\" ng-class=\"{'btn-info': dt.selected, active: isActive(dt)}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\" tabindex=\"-1\"><span ng-class=\"{'text-info': dt.current}\">{{dt.label}}</span></button>\n" +
|
3501
3907
|
" </td>\n" +
|
3502
3908
|
" </tr>\n" +
|
3503
3909
|
" </tbody>\n" +
|
@@ -3507,43 +3913,72 @@ angular.module("template/datepicker/datepicker.html", []).run(["$templateCache",
|
|
3507
3913
|
|
3508
3914
|
angular.module("template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
|
3509
3915
|
$templateCache.put("template/datepicker/popup.html",
|
3510
|
-
"<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
|
3916
|
+
"<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\" ng-keydown=\"keydown($event)\">\n" +
|
3511
3917
|
" <li ng-transclude></li>\n" +
|
3512
|
-
" <li ng-
|
3918
|
+
" <li ng-if=\"showButtonBar\" style=\"padding:10px 9px 2px\">\n" +
|
3513
3919
|
" <span class=\"btn-group\">\n" +
|
3514
|
-
" <button type=\"button\" class=\"btn btn-sm btn-info\" ng-click=\"today
|
3515
|
-
" <button type=\"button\" class=\"btn btn-sm btn-
|
3516
|
-
" <button type=\"button\" class=\"btn btn-sm btn-danger\" ng-click=\"clear()\">{{clearText}}</button>\n" +
|
3920
|
+
" <button type=\"button\" class=\"btn btn-sm btn-info\" ng-click=\"select('today')\">{{ getText('current') }}</button>\n" +
|
3921
|
+
" <button type=\"button\" class=\"btn btn-sm btn-danger\" ng-click=\"select(null)\">{{ getText('clear') }}</button>\n" +
|
3517
3922
|
" </span>\n" +
|
3518
|
-
" <button type=\"button\" class=\"btn btn-sm btn-success pull-right\" ng-click=\"
|
3923
|
+
" <button type=\"button\" class=\"btn btn-sm btn-success pull-right\" ng-click=\"close()\">{{ getText('close') }}</button>\n" +
|
3519
3924
|
" </li>\n" +
|
3520
3925
|
"</ul>\n" +
|
3521
3926
|
"");
|
3522
3927
|
}]);
|
3523
3928
|
|
3929
|
+
angular.module("template/datepicker/year.html", []).run(["$templateCache", function($templateCache) {
|
3930
|
+
$templateCache.put("template/datepicker/year.html",
|
3931
|
+
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
3932
|
+
" <thead>\n" +
|
3933
|
+
" <tr>\n" +
|
3934
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
|
3935
|
+
" <th colspan=\"3\"><button id=\"{{uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"toggleMode()\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
3936
|
+
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
|
3937
|
+
" </tr>\n" +
|
3938
|
+
" </thead>\n" +
|
3939
|
+
" <tbody>\n" +
|
3940
|
+
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
3941
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\" aria-disabled=\"{{!!dt.disabled}}\">\n" +
|
3942
|
+
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default\" ng-class=\"{'btn-info': dt.selected, active: isActive(dt)}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\" tabindex=\"-1\"><span ng-class=\"{'text-info': dt.current}\">{{dt.label}}</span></button>\n" +
|
3943
|
+
" </td>\n" +
|
3944
|
+
" </tr>\n" +
|
3945
|
+
" </tbody>\n" +
|
3946
|
+
"</table>\n" +
|
3947
|
+
"");
|
3948
|
+
}]);
|
3949
|
+
|
3524
3950
|
angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
|
3525
3951
|
$templateCache.put("template/modal/backdrop.html",
|
3526
|
-
"<div class=\"modal-backdrop fade\"
|
3952
|
+
"<div class=\"modal-backdrop fade\"\n" +
|
3953
|
+
" ng-class=\"{in: animate}\"\n" +
|
3954
|
+
" ng-style=\"{'z-index': 1040 + (index && 1 || 0) + index*10}\"\n" +
|
3955
|
+
"></div>\n" +
|
3956
|
+
"");
|
3527
3957
|
}]);
|
3528
3958
|
|
3529
3959
|
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
|
3530
3960
|
$templateCache.put("template/modal/window.html",
|
3531
|
-
"<div tabindex=\"-1\" class=\"modal fade
|
3532
|
-
" <div class=\"modal-dialog\"><div class=\"modal-content\" ng-transclude></div></div>\n" +
|
3961
|
+
"<div tabindex=\"-1\" role=\"dialog\" class=\"modal fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
|
3962
|
+
" <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content\" ng-transclude></div></div>\n" +
|
3533
3963
|
"</div>");
|
3534
3964
|
}]);
|
3535
3965
|
|
3536
3966
|
angular.module("template/pagination/pager.html", []).run(["$templateCache", function($templateCache) {
|
3537
3967
|
$templateCache.put("template/pagination/pager.html",
|
3538
3968
|
"<ul class=\"pager\">\n" +
|
3539
|
-
" <li ng-
|
3969
|
+
" <li ng-class=\"{disabled: noPrevious(), previous: align}\"><a href ng-click=\"selectPage(page - 1)\">{{getText('previous')}}</a></li>\n" +
|
3970
|
+
" <li ng-class=\"{disabled: noNext(), next: align}\"><a href ng-click=\"selectPage(page + 1)\">{{getText('next')}}</a></li>\n" +
|
3540
3971
|
"</ul>");
|
3541
3972
|
}]);
|
3542
3973
|
|
3543
3974
|
angular.module("template/pagination/pagination.html", []).run(["$templateCache", function($templateCache) {
|
3544
3975
|
$templateCache.put("template/pagination/pagination.html",
|
3545
3976
|
"<ul class=\"pagination\">\n" +
|
3546
|
-
" <li ng-
|
3977
|
+
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noPrevious()}\"><a href ng-click=\"selectPage(1)\">{{getText('first')}}</a></li>\n" +
|
3978
|
+
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noPrevious()}\"><a href ng-click=\"selectPage(page - 1)\">{{getText('previous')}}</a></li>\n" +
|
3979
|
+
" <li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active}\"><a href ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
|
3980
|
+
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noNext()}\"><a href ng-click=\"selectPage(page + 1)\">{{getText('next')}}</a></li>\n" +
|
3981
|
+
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noNext()}\"><a href ng-click=\"selectPage(totalPages)\">{{getText('last')}}</a></li>\n" +
|
3547
3982
|
"</ul>");
|
3548
3983
|
}]);
|
3549
3984
|
|
@@ -3580,7 +4015,7 @@ angular.module("template/popover/popover.html", []).run(["$templateCache", funct
|
|
3580
4015
|
|
3581
4016
|
angular.module("template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
|
3582
4017
|
$templateCache.put("template/progressbar/bar.html",
|
3583
|
-
"<div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" ng-transclude></div>");
|
4018
|
+
"<div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" role=\"progressbar\" aria-valuenow=\"{{value}}\" aria-valuemin=\"0\" aria-valuemax=\"{{max}}\" ng-style=\"{width: percent + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" ng-transclude></div>");
|
3584
4019
|
}]);
|
3585
4020
|
|
3586
4021
|
angular.module("template/progressbar/progress.html", []).run(["$templateCache", function($templateCache) {
|
@@ -3590,13 +4025,17 @@ angular.module("template/progressbar/progress.html", []).run(["$templateCache",
|
|
3590
4025
|
|
3591
4026
|
angular.module("template/progressbar/progressbar.html", []).run(["$templateCache", function($templateCache) {
|
3592
4027
|
$templateCache.put("template/progressbar/progressbar.html",
|
3593
|
-
"<div class=\"progress\"
|
4028
|
+
"<div class=\"progress\">\n" +
|
4029
|
+
" <div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" role=\"progressbar\" aria-valuenow=\"{{value}}\" aria-valuemin=\"0\" aria-valuemax=\"{{max}}\" ng-style=\"{width: percent + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" ng-transclude></div>\n" +
|
4030
|
+
"</div>");
|
3594
4031
|
}]);
|
3595
4032
|
|
3596
4033
|
angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
|
3597
4034
|
$templateCache.put("template/rating/rating.html",
|
3598
|
-
"<span ng-mouseleave=\"reset()\">\n" +
|
3599
|
-
" <i ng-repeat=\"r in range\" ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" class=\"glyphicon\" ng-class=\"$index <
|
4035
|
+
"<span ng-mouseleave=\"reset()\" ng-keydown=\"onKeydown($event)\" tabindex=\"0\" role=\"slider\" aria-valuemin=\"0\" aria-valuemax=\"{{range.length}}\" aria-valuenow=\"{{value}}\">\n" +
|
4036
|
+
" <i ng-repeat=\"r in range track by $index\" ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" class=\"glyphicon\" ng-class=\"$index < value && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')\">\n" +
|
4037
|
+
" <span class=\"sr-only\">({{ $index < value ? '*' : ' ' }})</span>\n" +
|
4038
|
+
" </i>\n" +
|
3600
4039
|
"</span>");
|
3601
4040
|
}]);
|
3602
4041
|
|
@@ -3618,8 +4057,8 @@ angular.module("template/tabs/tabset-titles.html", []).run(["$templateCache", fu
|
|
3618
4057
|
angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
|
3619
4058
|
$templateCache.put("template/tabs/tabset.html",
|
3620
4059
|
"\n" +
|
3621
|
-
"<div
|
3622
|
-
" <ul class=\"nav {{type
|
4060
|
+
"<div>\n" +
|
4061
|
+
" <ul class=\"nav nav-{{type || 'tabs'}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
|
3623
4062
|
" <div class=\"tab-content\">\n" +
|
3624
4063
|
" <div class=\"tab-pane\" \n" +
|
3625
4064
|
" ng-repeat=\"tab in tabs\" \n" +
|
@@ -3669,8 +4108,8 @@ angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCac
|
|
3669
4108
|
|
3670
4109
|
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
|
3671
4110
|
$templateCache.put("template/typeahead/typeahead-popup.html",
|
3672
|
-
"<ul class=\"dropdown-menu\" ng-
|
3673
|
-
" <li ng-repeat=\"match in matches\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\">\n" +
|
4111
|
+
"<ul class=\"dropdown-menu\" ng-if=\"isOpen()\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
|
4112
|
+
" <li ng-repeat=\"match in matches track by $index\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\" role=\"option\" id=\"{{match.id}}\">\n" +
|
3674
4113
|
" <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
|
3675
4114
|
" </li>\n" +
|
3676
4115
|
"</ul>");
|