angular-ui-bootstrap-rails 0.13.0 → 0.13.3
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: 59d59d03b0afa5ce0e3fcf95c11e8b109ea2b778
|
4
|
+
data.tar.gz: 2232fbd146aeba4da61b47fad18ec41397c6add8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09cbf801cb2571e2cacca5f3206eb24b2a1dd5743dd5b3f0630a8f81cc39956b15e39b0b60f5b818175353f68f3c2f7fc39c3c2a1a544f48ee93b6b675bc32d1
|
7
|
+
data.tar.gz: 2aa07b54f3147d270336f18aae6e51f6274d79dac79af00b326692af75463a6ac5ca054d661d65cb876a0d3a3f7c0411950a65b50a62202211109c84461b588e
|
@@ -2,11 +2,11 @@
|
|
2
2
|
* angular-ui-bootstrap
|
3
3
|
* http://angular-ui.github.io/bootstrap/
|
4
4
|
|
5
|
-
* Version: 0.13.
|
5
|
+
* Version: 0.13.3 - 2015-08-09
|
6
6
|
* License: MIT
|
7
7
|
*/
|
8
8
|
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "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.transition","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-popup.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/tooltip/tooltip-template-popup.html","template/popover/popover-template.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"]);
|
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-popup.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/tooltip/tooltip-template-popup.html","template/popover/popover-html.html","template/popover/popover-template.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.collapse', [])
|
11
11
|
|
12
12
|
.directive('collapse', ['$animate', function ($animate) {
|
@@ -14,7 +14,11 @@ angular.module('ui.bootstrap.collapse', [])
|
|
14
14
|
return {
|
15
15
|
link: function (scope, element, attrs) {
|
16
16
|
function expand() {
|
17
|
-
element.removeClass('collapse')
|
17
|
+
element.removeClass('collapse')
|
18
|
+
.addClass('collapsing')
|
19
|
+
.attr('aria-expanded', true)
|
20
|
+
.attr('aria-hidden', false);
|
21
|
+
|
18
22
|
$animate.addClass(element, 'in', {
|
19
23
|
to: { height: element[0].scrollHeight + 'px' }
|
20
24
|
}).then(expandDone);
|
@@ -26,6 +30,10 @@ angular.module('ui.bootstrap.collapse', [])
|
|
26
30
|
}
|
27
31
|
|
28
32
|
function collapse() {
|
33
|
+
if(! element.hasClass('collapse') && ! element.hasClass('in')) {
|
34
|
+
return collapseDone();
|
35
|
+
}
|
36
|
+
|
29
37
|
element
|
30
38
|
// IMPORTANT: The height must be set before adding "collapsing" class.
|
31
39
|
// Otherwise, the browser attempts to animate from height 0 (in
|
@@ -34,7 +42,9 @@ angular.module('ui.bootstrap.collapse', [])
|
|
34
42
|
// initially all panel collapse have the collapse class, this removal
|
35
43
|
// prevents the animation from jumping to collapsed state
|
36
44
|
.removeClass('collapse')
|
37
|
-
.addClass('collapsing')
|
45
|
+
.addClass('collapsing')
|
46
|
+
.attr('aria-expanded', false)
|
47
|
+
.attr('aria-hidden', true);
|
38
48
|
|
39
49
|
$animate.removeClass(element, 'in', {
|
40
50
|
to: {height: '0'}
|
@@ -105,11 +115,14 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
105
115
|
// and adds an accordion CSS class to itself element.
|
106
116
|
.directive('accordion', function () {
|
107
117
|
return {
|
108
|
-
restrict:'EA',
|
109
|
-
controller:'AccordionController',
|
118
|
+
restrict: 'EA',
|
119
|
+
controller: 'AccordionController',
|
120
|
+
controllerAs: 'accordion',
|
110
121
|
transclude: true,
|
111
122
|
replace: false,
|
112
|
-
templateUrl:
|
123
|
+
templateUrl: function(element, attrs) {
|
124
|
+
return attrs.templateUrl || 'template/accordion/accordion.html';
|
125
|
+
}
|
113
126
|
};
|
114
127
|
})
|
115
128
|
|
@@ -120,7 +133,9 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
120
133
|
restrict:'EA',
|
121
134
|
transclude:true, // It transcludes the contents of the directive into the template
|
122
135
|
replace: true, // The element containing the directive will be replaced with the template
|
123
|
-
templateUrl:
|
136
|
+
templateUrl: function(element, attrs) {
|
137
|
+
return attrs.templateUrl || 'template/accordion/accordion-group.html';
|
138
|
+
},
|
124
139
|
scope: {
|
125
140
|
heading: '@', // Interpolate the heading attribute onto this scope
|
126
141
|
isOpen: '=?',
|
@@ -181,8 +196,8 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
181
196
|
link: function(scope, element, attr, controller) {
|
182
197
|
scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
|
183
198
|
if ( heading ) {
|
184
|
-
element.html('');
|
185
|
-
element.append(heading);
|
199
|
+
element.find('span').html('');
|
200
|
+
element.find('span').append(heading);
|
186
201
|
}
|
187
202
|
});
|
188
203
|
}
|
@@ -194,17 +209,20 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
194
209
|
angular.module('ui.bootstrap.alert', [])
|
195
210
|
|
196
211
|
.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
|
197
|
-
$scope.closeable =
|
212
|
+
$scope.closeable = !!$attrs.close;
|
198
213
|
this.close = $scope.close;
|
199
214
|
}])
|
200
215
|
|
201
216
|
.directive('alert', function () {
|
202
217
|
return {
|
203
|
-
restrict:'EA',
|
204
|
-
controller:'AlertController',
|
205
|
-
|
206
|
-
|
207
|
-
|
218
|
+
restrict: 'EA',
|
219
|
+
controller: 'AlertController',
|
220
|
+
controllerAs: 'alert',
|
221
|
+
templateUrl: function(element, attrs) {
|
222
|
+
return attrs.templateUrl || 'template/alert/alert.html';
|
223
|
+
},
|
224
|
+
transclude: true,
|
225
|
+
replace: true,
|
208
226
|
scope: {
|
209
227
|
type: '@',
|
210
228
|
close: '&'
|
@@ -225,14 +243,19 @@ angular.module('ui.bootstrap.alert', [])
|
|
225
243
|
|
226
244
|
angular.module('ui.bootstrap.bindHtml', [])
|
227
245
|
|
228
|
-
.
|
246
|
+
.value('$bindHtmlUnsafeSuppressDeprecated', false)
|
247
|
+
|
248
|
+
.directive('bindHtmlUnsafe', ['$log', '$bindHtmlUnsafeSuppressDeprecated', function ($log, $bindHtmlUnsafeSuppressDeprecated) {
|
229
249
|
return function (scope, element, attr) {
|
250
|
+
if (!$bindHtmlUnsafeSuppressDeprecated) {
|
251
|
+
$log.warn('bindHtmlUnsafe is now deprecated. Use ngBindHtml instead');
|
252
|
+
}
|
230
253
|
element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
|
231
254
|
scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
|
232
255
|
element.html(value || '');
|
233
256
|
});
|
234
257
|
};
|
235
|
-
});
|
258
|
+
}]);
|
236
259
|
angular.module('ui.bootstrap.buttons', [])
|
237
260
|
|
238
261
|
.constant('buttonConfig', {
|
@@ -249,6 +272,7 @@ angular.module('ui.bootstrap.buttons', [])
|
|
249
272
|
return {
|
250
273
|
require: ['btnRadio', 'ngModel'],
|
251
274
|
controller: 'ButtonsController',
|
275
|
+
controllerAs: 'buttons',
|
252
276
|
link: function (scope, element, attrs, ctrls) {
|
253
277
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
254
278
|
|
@@ -259,6 +283,10 @@ angular.module('ui.bootstrap.buttons', [])
|
|
259
283
|
|
260
284
|
//ui->model
|
261
285
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
286
|
+
if (attrs.disabled) {
|
287
|
+
return;
|
288
|
+
}
|
289
|
+
|
262
290
|
var isActive = element.hasClass(buttonsCtrl.activeClass);
|
263
291
|
|
264
292
|
if (!isActive || angular.isDefined(attrs.uncheckable)) {
|
@@ -276,6 +304,7 @@ angular.module('ui.bootstrap.buttons', [])
|
|
276
304
|
return {
|
277
305
|
require: ['btnCheckbox', 'ngModel'],
|
278
306
|
controller: 'ButtonsController',
|
307
|
+
controllerAs: 'button',
|
279
308
|
link: function (scope, element, attrs, ctrls) {
|
280
309
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
281
310
|
|
@@ -299,6 +328,10 @@ angular.module('ui.bootstrap.buttons', [])
|
|
299
328
|
|
300
329
|
//ui->model
|
301
330
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
331
|
+
if (attrs.disabled) {
|
332
|
+
return;
|
333
|
+
}
|
334
|
+
|
302
335
|
scope.$apply(function () {
|
303
336
|
ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
|
304
337
|
ngModelCtrl.$render();
|
@@ -317,9 +350,12 @@ angular.module('ui.bootstrap.buttons', [])
|
|
317
350
|
*
|
318
351
|
*/
|
319
352
|
angular.module('ui.bootstrap.carousel', [])
|
320
|
-
.controller('CarouselController', ['$scope', '$interval', '$animate', function ($scope, $interval, $animate) {
|
353
|
+
.controller('CarouselController', ['$scope', '$element', '$interval', '$animate', function ($scope, $element, $interval, $animate) {
|
321
354
|
var self = this,
|
322
355
|
slides = self.slides = $scope.slides = [],
|
356
|
+
NEW_ANIMATE = angular.version.minor >= 4,
|
357
|
+
NO_TRANSITION = 'uib-noTransition',
|
358
|
+
SLIDE_DIRECTION = 'uib-slideDirection',
|
323
359
|
currentIndex = -1,
|
324
360
|
currentInterval, isPlaying;
|
325
361
|
self.currentSlide = null;
|
@@ -327,33 +363,52 @@ angular.module('ui.bootstrap.carousel', [])
|
|
327
363
|
var destroyed = false;
|
328
364
|
/* direction: "prev" or "next" */
|
329
365
|
self.select = $scope.select = function(nextSlide, direction) {
|
330
|
-
var nextIndex =
|
366
|
+
var nextIndex = $scope.indexOfSlide(nextSlide);
|
331
367
|
//Decide direction if it's not given
|
332
368
|
if (direction === undefined) {
|
333
369
|
direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev';
|
334
370
|
}
|
335
|
-
if
|
336
|
-
|
371
|
+
//Prevent this user-triggered transition from occurring if there is already one in progress
|
372
|
+
if (nextSlide && nextSlide !== self.currentSlide && !$scope.$currentTransition) {
|
373
|
+
goNext(nextSlide, nextIndex, direction);
|
337
374
|
}
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
375
|
+
};
|
376
|
+
|
377
|
+
function goNext(slide, index, direction) {
|
378
|
+
// Scope has been destroyed, stop here.
|
379
|
+
if (destroyed) { return; }
|
380
|
+
|
381
|
+
angular.extend(slide, {direction: direction, active: true});
|
382
|
+
angular.extend(self.currentSlide || {}, {direction: direction, active: false});
|
383
|
+
if ($animate.enabled() && !$scope.noTransition && !$scope.$currentTransition &&
|
384
|
+
slide.$element && self.slides.length > 1) {
|
385
|
+
slide.$element.data(SLIDE_DIRECTION, slide.direction);
|
386
|
+
if (self.currentSlide && self.currentSlide.$element) {
|
387
|
+
self.currentSlide.$element.data(SLIDE_DIRECTION, slide.direction);
|
388
|
+
}
|
389
|
+
|
390
|
+
$scope.$currentTransition = true;
|
391
|
+
if (NEW_ANIMATE) {
|
392
|
+
$animate.on('addClass', slide.$element, function (element, phase) {
|
393
|
+
if (phase === 'close') {
|
394
|
+
$scope.$currentTransition = null;
|
395
|
+
$animate.off('addClass', element);
|
396
|
+
}
|
397
|
+
});
|
398
|
+
} else {
|
399
|
+
slide.$element.one('$animate:close', function closeFn() {
|
347
400
|
$scope.$currentTransition = null;
|
348
401
|
});
|
349
402
|
}
|
350
|
-
|
351
|
-
self.currentSlide = nextSlide;
|
352
|
-
currentIndex = nextIndex;
|
353
|
-
//every time you change slides, reset the timer
|
354
|
-
restartTimer();
|
355
403
|
}
|
356
|
-
|
404
|
+
|
405
|
+
self.currentSlide = slide;
|
406
|
+
currentIndex = index;
|
407
|
+
|
408
|
+
//every time you change slides, reset the timer
|
409
|
+
restartTimer();
|
410
|
+
}
|
411
|
+
|
357
412
|
$scope.$on('$destroy', function () {
|
358
413
|
destroyed = true;
|
359
414
|
});
|
@@ -378,26 +433,30 @@ angular.module('ui.bootstrap.carousel', [])
|
|
378
433
|
};
|
379
434
|
|
380
435
|
/* Allow outside people to call indexOf on slides array */
|
381
|
-
|
436
|
+
$scope.indexOfSlide = function(slide) {
|
382
437
|
return angular.isDefined(slide.index) ? +slide.index : slides.indexOf(slide);
|
383
438
|
};
|
384
439
|
|
385
440
|
$scope.next = function() {
|
386
441
|
var newIndex = (self.getCurrentIndex() + 1) % slides.length;
|
387
442
|
|
388
|
-
|
389
|
-
|
390
|
-
return
|
443
|
+
if (newIndex === 0 && $scope.noWrap()) {
|
444
|
+
$scope.pause();
|
445
|
+
return;
|
391
446
|
}
|
447
|
+
|
448
|
+
return self.select(getSlideByIndex(newIndex), 'next');
|
392
449
|
};
|
393
450
|
|
394
451
|
$scope.prev = function() {
|
395
452
|
var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1;
|
396
453
|
|
397
|
-
|
398
|
-
|
399
|
-
return
|
454
|
+
if ($scope.noWrap() && newIndex === slides.length - 1){
|
455
|
+
$scope.pause();
|
456
|
+
return;
|
400
457
|
}
|
458
|
+
|
459
|
+
return self.select(getSlideByIndex(newIndex), 'prev');
|
401
460
|
};
|
402
461
|
|
403
462
|
$scope.isActive = function(slide) {
|
@@ -424,7 +483,7 @@ angular.module('ui.bootstrap.carousel', [])
|
|
424
483
|
|
425
484
|
function timerFn() {
|
426
485
|
var interval = +$scope.interval;
|
427
|
-
if (isPlaying && !isNaN(interval) && interval > 0) {
|
486
|
+
if (isPlaying && !isNaN(interval) && interval > 0 && slides.length) {
|
428
487
|
$scope.next();
|
429
488
|
} else {
|
430
489
|
$scope.pause();
|
@@ -476,8 +535,17 @@ angular.module('ui.bootstrap.carousel', [])
|
|
476
535
|
} else if (currentIndex > index) {
|
477
536
|
currentIndex--;
|
478
537
|
}
|
538
|
+
|
539
|
+
//clean the currentSlide when no more slide
|
540
|
+
if (slides.length === 0) {
|
541
|
+
self.currentSlide = null;
|
542
|
+
}
|
479
543
|
};
|
480
544
|
|
545
|
+
$scope.$watch('noTransition', function(noTransition) {
|
546
|
+
$element.data(NO_TRANSITION, noTransition);
|
547
|
+
});
|
548
|
+
|
481
549
|
}])
|
482
550
|
|
483
551
|
/**
|
@@ -524,12 +592,16 @@ angular.module('ui.bootstrap.carousel', [])
|
|
524
592
|
transclude: true,
|
525
593
|
replace: true,
|
526
594
|
controller: 'CarouselController',
|
595
|
+
controllerAs: 'carousel',
|
527
596
|
require: 'carousel',
|
528
|
-
templateUrl:
|
597
|
+
templateUrl: function(element, attrs) {
|
598
|
+
return attrs.templateUrl || 'template/carousel/carousel.html';
|
599
|
+
},
|
529
600
|
scope: {
|
530
601
|
interval: '=',
|
531
602
|
noTransition: '=',
|
532
|
-
noPause: '='
|
603
|
+
noPause: '=',
|
604
|
+
noWrap: '&'
|
533
605
|
}
|
534
606
|
};
|
535
607
|
}])
|
@@ -582,7 +654,9 @@ function CarouselDemoCtrl($scope) {
|
|
582
654
|
restrict: 'EA',
|
583
655
|
transclude: true,
|
584
656
|
replace: true,
|
585
|
-
templateUrl:
|
657
|
+
templateUrl: function(element, attrs) {
|
658
|
+
return attrs.templateUrl || 'template/carousel/slide.html';
|
659
|
+
},
|
586
660
|
scope: {
|
587
661
|
active: '=?',
|
588
662
|
index: '=?'
|
@@ -604,23 +678,47 @@ function CarouselDemoCtrl($scope) {
|
|
604
678
|
})
|
605
679
|
|
606
680
|
.animation('.item', [
|
607
|
-
'$animate',
|
608
|
-
function ($animate) {
|
681
|
+
'$injector', '$animate',
|
682
|
+
function ($injector, $animate) {
|
683
|
+
var NO_TRANSITION = 'uib-noTransition',
|
684
|
+
SLIDE_DIRECTION = 'uib-slideDirection',
|
685
|
+
$animateCss = null;
|
686
|
+
|
687
|
+
if ($injector.has('$animateCss')) {
|
688
|
+
$animateCss = $injector.get('$animateCss');
|
689
|
+
}
|
690
|
+
|
691
|
+
function removeClass(element, className, callback) {
|
692
|
+
element.removeClass(className);
|
693
|
+
if (callback) {
|
694
|
+
callback();
|
695
|
+
}
|
696
|
+
}
|
697
|
+
|
609
698
|
return {
|
610
699
|
beforeAddClass: function (element, className, done) {
|
611
700
|
// Due to transclusion, noTransition property is on parent's scope
|
612
701
|
if (className == 'active' && element.parent() &&
|
613
|
-
!element.parent().
|
702
|
+
!element.parent().data(NO_TRANSITION)) {
|
614
703
|
var stopped = false;
|
615
|
-
var direction = element.
|
704
|
+
var direction = element.data(SLIDE_DIRECTION);
|
616
705
|
var directionClass = direction == 'next' ? 'left' : 'right';
|
706
|
+
var removeClassFn = removeClass.bind(this, element,
|
707
|
+
directionClass + ' ' + direction, done);
|
617
708
|
element.addClass(direction);
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
}
|
709
|
+
|
710
|
+
if ($animateCss) {
|
711
|
+
$animateCss(element, {addClass: directionClass})
|
712
|
+
.start()
|
713
|
+
.done(removeClassFn);
|
714
|
+
} else {
|
715
|
+
$animate.addClass(element, directionClass).then(function () {
|
716
|
+
if (!stopped) {
|
717
|
+
removeClassFn();
|
718
|
+
}
|
719
|
+
done();
|
720
|
+
});
|
721
|
+
}
|
624
722
|
|
625
723
|
return function () {
|
626
724
|
stopped = true;
|
@@ -630,17 +728,25 @@ function ($animate) {
|
|
630
728
|
},
|
631
729
|
beforeRemoveClass: function (element, className, done) {
|
632
730
|
// Due to transclusion, noTransition property is on parent's scope
|
633
|
-
if (className
|
634
|
-
!element.parent().
|
731
|
+
if (className === 'active' && element.parent() &&
|
732
|
+
!element.parent().data(NO_TRANSITION)) {
|
635
733
|
var stopped = false;
|
636
|
-
var direction = element.
|
734
|
+
var direction = element.data(SLIDE_DIRECTION);
|
637
735
|
var directionClass = direction == 'next' ? 'left' : 'right';
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
}
|
642
|
-
|
643
|
-
|
736
|
+
var removeClassFn = removeClass.bind(this, element, directionClass, done);
|
737
|
+
|
738
|
+
if ($animateCss) {
|
739
|
+
$animateCss(element, {addClass: directionClass})
|
740
|
+
.start()
|
741
|
+
.done(removeClassFn);
|
742
|
+
} else {
|
743
|
+
$animate.addClass(element, directionClass).then(function () {
|
744
|
+
if (!stopped) {
|
745
|
+
removeClassFn();
|
746
|
+
}
|
747
|
+
done();
|
748
|
+
});
|
749
|
+
}
|
644
750
|
return function () {
|
645
751
|
stopped = true;
|
646
752
|
};
|
@@ -656,7 +762,7 @@ function ($animate) {
|
|
656
762
|
|
657
763
|
angular.module('ui.bootstrap.dateparser', [])
|
658
764
|
|
659
|
-
.service('dateParser', ['$locale', 'orderByFilter', function($locale, orderByFilter) {
|
765
|
+
.service('dateParser', ['$log', '$locale', 'orderByFilter', function($log, $locale, orderByFilter) {
|
660
766
|
// Pulled from https://github.com/mbostock/d3/blob/master/src/format/requote.js
|
661
767
|
var SPECIAL_CHARACTERS_REGEXP = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
|
662
768
|
|
@@ -709,6 +815,10 @@ angular.module('ui.bootstrap.dateparser', [])
|
|
709
815
|
regex: '(?:0|1)[0-9]|2[0-3]',
|
710
816
|
apply: function(value) { this.hours = +value; }
|
711
817
|
},
|
818
|
+
'hh': {
|
819
|
+
regex: '0[0-9]|1[0-2]',
|
820
|
+
apply: function(value) { this.hours = +value; }
|
821
|
+
},
|
712
822
|
'H': {
|
713
823
|
regex: '1?[0-9]|2[0-3]',
|
714
824
|
apply: function(value) { this.hours = +value; }
|
@@ -732,6 +842,18 @@ angular.module('ui.bootstrap.dateparser', [])
|
|
732
842
|
's': {
|
733
843
|
regex: '[0-9]|[1-5][0-9]',
|
734
844
|
apply: function(value) { this.seconds = +value; }
|
845
|
+
},
|
846
|
+
'a': {
|
847
|
+
regex: $locale.DATETIME_FORMATS.AMPMS.join('|'),
|
848
|
+
apply: function(value) {
|
849
|
+
if (this.hours === 12) {
|
850
|
+
this.hours = 0;
|
851
|
+
}
|
852
|
+
|
853
|
+
if (value === 'PM') {
|
854
|
+
this.hours += 12;
|
855
|
+
}
|
856
|
+
}
|
735
857
|
}
|
736
858
|
};
|
737
859
|
|
@@ -781,7 +903,7 @@ angular.module('ui.bootstrap.dateparser', [])
|
|
781
903
|
|
782
904
|
if ( results && results.length ) {
|
783
905
|
var fields, dt;
|
784
|
-
if (baseDate) {
|
906
|
+
if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) {
|
785
907
|
fields = {
|
786
908
|
year: baseDate.getFullYear(),
|
787
909
|
month: baseDate.getMonth(),
|
@@ -792,6 +914,9 @@ angular.module('ui.bootstrap.dateparser', [])
|
|
792
914
|
milliseconds: baseDate.getMilliseconds()
|
793
915
|
};
|
794
916
|
} else {
|
917
|
+
if (baseDate) {
|
918
|
+
$log.warn('dateparser:', 'baseDate is not a valid date');
|
919
|
+
}
|
795
920
|
fields = { year: 1900, month: 0, date: 1, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 };
|
796
921
|
}
|
797
922
|
|
@@ -985,6 +1110,8 @@ angular.module('ui.bootstrap.position', [])
|
|
985
1110
|
|
986
1111
|
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootstrap.position'])
|
987
1112
|
|
1113
|
+
.value('$datepickerSuppressError', false)
|
1114
|
+
|
988
1115
|
.constant('datepickerConfig', {
|
989
1116
|
formatDay: 'dd',
|
990
1117
|
formatMonth: 'MMMM',
|
@@ -1003,7 +1130,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1003
1130
|
shortcutPropagation: false
|
1004
1131
|
})
|
1005
1132
|
|
1006
|
-
.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$
|
1133
|
+
.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$log', 'dateFilter', 'datepickerConfig', '$datepickerSuppressError', function($scope, $attrs, $parse, $interpolate, $log, dateFilter, datepickerConfig, $datepickerSuppressError) {
|
1007
1134
|
var self = this,
|
1008
1135
|
ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl;
|
1009
1136
|
|
@@ -1012,8 +1139,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1012
1139
|
|
1013
1140
|
// Configuration attributes
|
1014
1141
|
angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle',
|
1015
|
-
'
|
1016
|
-
self[key] = angular.isDefined($attrs[key]) ? (index <
|
1142
|
+
'showWeeks', 'startingDay', 'yearRange', 'shortcutPropagation'], function( key, index ) {
|
1143
|
+
self[key] = angular.isDefined($attrs[key]) ? (index < 6 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key];
|
1017
1144
|
});
|
1018
1145
|
|
1019
1146
|
// Watchable date attributes
|
@@ -1028,8 +1155,22 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1028
1155
|
}
|
1029
1156
|
});
|
1030
1157
|
|
1158
|
+
angular.forEach(['minMode', 'maxMode'], function( key ) {
|
1159
|
+
if ( $attrs[key] ) {
|
1160
|
+
$scope.$parent.$watch($parse($attrs[key]), function(value) {
|
1161
|
+
self[key] = angular.isDefined(value) ? value : $attrs[key];
|
1162
|
+
$scope[key] = self[key];
|
1163
|
+
if ((key == 'minMode' && self.modes.indexOf( $scope.datepickerMode ) < self.modes.indexOf( self[key] )) || (key == 'maxMode' && self.modes.indexOf( $scope.datepickerMode ) > self.modes.indexOf( self[key] ))) {
|
1164
|
+
$scope.datepickerMode = self[key];
|
1165
|
+
}
|
1166
|
+
});
|
1167
|
+
} else {
|
1168
|
+
self[key] = datepickerConfig[key] || null;
|
1169
|
+
$scope[key] = self[key];
|
1170
|
+
}
|
1171
|
+
});
|
1172
|
+
|
1031
1173
|
$scope.datepickerMode = $scope.datepickerMode || datepickerConfig.datepickerMode;
|
1032
|
-
$scope.maxMode = self.maxMode;
|
1033
1174
|
$scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000);
|
1034
1175
|
|
1035
1176
|
if(angular.isDefined($attrs.initDate)) {
|
@@ -1067,10 +1208,9 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1067
1208
|
|
1068
1209
|
if ( isValid ) {
|
1069
1210
|
this.activeDate = date;
|
1070
|
-
} else {
|
1211
|
+
} else if ( !$datepickerSuppressError ) {
|
1071
1212
|
$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.');
|
1072
1213
|
}
|
1073
|
-
ngModelCtrl.$setValidity('date', isValid);
|
1074
1214
|
}
|
1075
1215
|
this.refreshView();
|
1076
1216
|
};
|
@@ -1080,7 +1220,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1080
1220
|
this._refreshView();
|
1081
1221
|
|
1082
1222
|
var date = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;
|
1083
|
-
ngModelCtrl.$setValidity('
|
1223
|
+
ngModelCtrl.$setValidity('dateDisabled', !date || (this.element && !this.isDisabled(date)));
|
1084
1224
|
}
|
1085
1225
|
};
|
1086
1226
|
|
@@ -1100,9 +1240,9 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1100
1240
|
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})));
|
1101
1241
|
};
|
1102
1242
|
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1243
|
+
this.customClass = function( date ) {
|
1244
|
+
return $scope.customClass({date: date, mode: $scope.datepickerMode});
|
1245
|
+
};
|
1106
1246
|
|
1107
1247
|
// Split array into smaller arrays
|
1108
1248
|
this.split = function(arr, size) {
|
@@ -1113,6 +1253,17 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1113
1253
|
return arrays;
|
1114
1254
|
};
|
1115
1255
|
|
1256
|
+
// Fix a hard-reprodusible bug with timezones
|
1257
|
+
// The bug depends on OS, browser, current timezone and current date
|
1258
|
+
// i.e.
|
1259
|
+
// var date = new Date(2014, 0, 1);
|
1260
|
+
// console.log(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());
|
1261
|
+
// can result in "2013 11 31 23" because of the bug.
|
1262
|
+
this.fixTimeZone = function(date) {
|
1263
|
+
var hours = date.getHours();
|
1264
|
+
date.setHours(hours === 23 ? hours + 2 : 0);
|
1265
|
+
};
|
1266
|
+
|
1116
1267
|
$scope.select = function( date ) {
|
1117
1268
|
if ( $scope.datepickerMode === self.minMode ) {
|
1118
1269
|
var dt = ngModelCtrl.$viewValue ? new Date( ngModelCtrl.$viewValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
|
@@ -1146,9 +1297,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1146
1297
|
$scope.keys = { 13:'enter', 32:'space', 33:'pageup', 34:'pagedown', 35:'end', 36:'home', 37:'left', 38:'up', 39:'right', 40:'down' };
|
1147
1298
|
|
1148
1299
|
var focusElement = function() {
|
1149
|
-
|
1150
|
-
self.element[0].focus();
|
1151
|
-
}, 0 , false);
|
1300
|
+
self.element[0].focus();
|
1152
1301
|
};
|
1153
1302
|
|
1154
1303
|
// Listen for focus requests from popup directive
|
@@ -1186,21 +1335,22 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1186
1335
|
return {
|
1187
1336
|
restrict: 'EA',
|
1188
1337
|
replace: true,
|
1189
|
-
templateUrl:
|
1338
|
+
templateUrl: function(element, attrs) {
|
1339
|
+
return attrs.templateUrl || 'template/datepicker/datepicker.html';
|
1340
|
+
},
|
1190
1341
|
scope: {
|
1191
1342
|
datepickerMode: '=?',
|
1192
1343
|
dateDisabled: '&',
|
1193
1344
|
customClass: '&',
|
1194
1345
|
shortcutPropagation: '&?'
|
1195
1346
|
},
|
1196
|
-
require: ['datepicker', '
|
1347
|
+
require: ['datepicker', '^ngModel'],
|
1197
1348
|
controller: 'DatepickerController',
|
1349
|
+
controllerAs: 'datepicker',
|
1198
1350
|
link: function(scope, element, attrs, ctrls) {
|
1199
1351
|
var datepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
1200
1352
|
|
1201
|
-
|
1202
|
-
datepickerCtrl.init( ngModelCtrl );
|
1203
|
-
}
|
1353
|
+
datepickerCtrl.init(ngModelCtrl);
|
1204
1354
|
}
|
1205
1355
|
};
|
1206
1356
|
})
|
@@ -1223,10 +1373,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1223
1373
|
}
|
1224
1374
|
|
1225
1375
|
function getDates(startDate, n) {
|
1226
|
-
var dates = new Array(n), current = new Date(startDate), i = 0;
|
1227
|
-
current.setHours(12); // Prevent repeated dates because of timezone bug
|
1376
|
+
var dates = new Array(n), current = new Date(startDate), i = 0, date;
|
1228
1377
|
while ( i < n ) {
|
1229
|
-
|
1378
|
+
date = new Date(current);
|
1379
|
+
ctrl.fixTimeZone(date);
|
1380
|
+
dates[i++] = date;
|
1230
1381
|
current.setDate( current.getDate() + 1 );
|
1231
1382
|
}
|
1232
1383
|
return dates;
|
@@ -1328,10 +1479,13 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1328
1479
|
|
1329
1480
|
ctrl._refreshView = function() {
|
1330
1481
|
var months = new Array(12),
|
1331
|
-
year = ctrl.activeDate.getFullYear()
|
1482
|
+
year = ctrl.activeDate.getFullYear(),
|
1483
|
+
date;
|
1332
1484
|
|
1333
1485
|
for ( var i = 0; i < 12; i++ ) {
|
1334
|
-
|
1486
|
+
date = new Date(year, i, 1);
|
1487
|
+
ctrl.fixTimeZone(date);
|
1488
|
+
months[i] = angular.extend(ctrl.createDateObject(date, ctrl.formatMonth), {
|
1335
1489
|
uid: scope.uniqueId + '-' + i
|
1336
1490
|
});
|
1337
1491
|
}
|
@@ -1388,10 +1542,12 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1388
1542
|
}
|
1389
1543
|
|
1390
1544
|
ctrl._refreshView = function() {
|
1391
|
-
var years = new Array(range);
|
1545
|
+
var years = new Array(range), date;
|
1392
1546
|
|
1393
1547
|
for ( var i = 0, start = getStartingYear(ctrl.activeDate.getFullYear()); i < range; i++ ) {
|
1394
|
-
|
1548
|
+
date = new Date(start + i, 0, 1);
|
1549
|
+
ctrl.fixTimeZone(date);
|
1550
|
+
years[i] = angular.extend(ctrl.createDateObject(date, ctrl.formatYear), {
|
1395
1551
|
uid: scope.uniqueId + '-' + i
|
1396
1552
|
});
|
1397
1553
|
}
|
@@ -1432,6 +1588,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1432
1588
|
|
1433
1589
|
.constant('datepickerPopupConfig', {
|
1434
1590
|
datepickerPopup: 'yyyy-MM-dd',
|
1591
|
+
datepickerPopupTemplateUrl: 'template/datepicker/popup.html',
|
1592
|
+
datepickerTemplateUrl: 'template/datepicker/datepicker.html',
|
1435
1593
|
html5Types: {
|
1436
1594
|
date: 'yyyy-MM-dd',
|
1437
1595
|
'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss',
|
@@ -1442,11 +1600,12 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
|
|
1442
1600
|
closeText: 'Done',
|
1443
1601
|
closeOnDateSelection: true,
|
1444
1602
|
appendToBody: false,
|
1445
|
-
showButtonBar: true
|
1603
|
+
showButtonBar: true,
|
1604
|
+
onOpenFocus: true
|
1446
1605
|
})
|
1447
1606
|
|
1448
|
-
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
|
1449
|
-
function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
|
1607
|
+
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$rootScope', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig', '$timeout',
|
1608
|
+
function ($compile, $parse, $document, $rootScope, $position, dateFilter, dateParser, datepickerPopupConfig, $timeout) {
|
1450
1609
|
return {
|
1451
1610
|
restrict: 'EA',
|
1452
1611
|
require: 'ngModel',
|
@@ -1461,7 +1620,10 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1461
1620
|
link: function(scope, element, attrs, ngModel) {
|
1462
1621
|
var dateFormat,
|
1463
1622
|
closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$parent.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
|
1464
|
-
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody
|
1623
|
+
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody,
|
1624
|
+
onOpenFocus = angular.isDefined(attrs.onOpenFocus) ? scope.$parent.$eval(attrs.onOpenFocus) : datepickerPopupConfig.onOpenFocus,
|
1625
|
+
datepickerPopupTemplateUrl = angular.isDefined(attrs.datepickerPopupTemplateUrl) ? attrs.datepickerPopupTemplateUrl : datepickerPopupConfig.datepickerPopupTemplateUrl,
|
1626
|
+
datepickerTemplateUrl = angular.isDefined(attrs.datepickerTemplateUrl) ? attrs.datepickerTemplateUrl : datepickerPopupConfig.datepickerTemplateUrl;
|
1465
1627
|
|
1466
1628
|
scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
|
1467
1629
|
|
@@ -1502,7 +1664,8 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1502
1664
|
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
|
1503
1665
|
popupEl.attr({
|
1504
1666
|
'ng-model': 'date',
|
1505
|
-
'ng-change': 'dateSelection()'
|
1667
|
+
'ng-change': 'dateSelection(date)',
|
1668
|
+
'template-url': datepickerPopupTemplateUrl
|
1506
1669
|
});
|
1507
1670
|
|
1508
1671
|
function cameltoDash( string ){
|
@@ -1511,6 +1674,8 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1511
1674
|
|
1512
1675
|
// datepicker element
|
1513
1676
|
var datepickerEl = angular.element(popupEl.children()[0]);
|
1677
|
+
datepickerEl.attr('template-url', datepickerTemplateUrl);
|
1678
|
+
|
1514
1679
|
if (isHtml5DateInput) {
|
1515
1680
|
if (attrs.type == 'month') {
|
1516
1681
|
datepickerEl.attr('datepicker-mode', '"month"');
|
@@ -1520,7 +1685,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1520
1685
|
|
1521
1686
|
if ( attrs.datepickerOptions ) {
|
1522
1687
|
var options = scope.$parent.$eval(attrs.datepickerOptions);
|
1523
|
-
if(options.initDate) {
|
1688
|
+
if(options && options.initDate) {
|
1524
1689
|
scope.initDate = options.initDate;
|
1525
1690
|
datepickerEl.attr( 'init-date', 'initDate' );
|
1526
1691
|
delete options.initDate;
|
@@ -1531,7 +1696,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1531
1696
|
}
|
1532
1697
|
|
1533
1698
|
scope.watchData = {};
|
1534
|
-
angular.forEach(['minDate', 'maxDate', 'datepickerMode', 'initDate', 'shortcutPropagation'], function( key ) {
|
1699
|
+
angular.forEach(['minMode', 'maxMode', 'minDate', 'maxDate', 'datepickerMode', 'initDate', 'shortcutPropagation'], function( key ) {
|
1535
1700
|
if ( attrs[key] ) {
|
1536
1701
|
var getAttribute = $parse(attrs[key]);
|
1537
1702
|
scope.$parent.$watch(getAttribute, function(value){
|
@@ -1543,7 +1708,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1543
1708
|
if ( key === 'datepickerMode' ) {
|
1544
1709
|
var setAttribute = getAttribute.assign;
|
1545
1710
|
scope.$watch('watchData.' + key, function(value, oldvalue) {
|
1546
|
-
if ( value !== oldvalue ) {
|
1711
|
+
if ( angular.isFunction(setAttribute) && value !== oldvalue ) {
|
1547
1712
|
setAttribute(scope.$parent, value);
|
1548
1713
|
}
|
1549
1714
|
});
|
@@ -1573,7 +1738,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1573
1738
|
} else if (angular.isDate(viewValue) && !isNaN(viewValue)) {
|
1574
1739
|
return viewValue;
|
1575
1740
|
} else if (angular.isString(viewValue)) {
|
1576
|
-
var date = dateParser.parse(viewValue, dateFormat, scope.date)
|
1741
|
+
var date = dateParser.parse(viewValue, dateFormat, scope.date);
|
1577
1742
|
if (isNaN(date)) {
|
1578
1743
|
return undefined;
|
1579
1744
|
} else {
|
@@ -1586,6 +1751,11 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1586
1751
|
|
1587
1752
|
function validator(modelValue, viewValue) {
|
1588
1753
|
var value = modelValue || viewValue;
|
1754
|
+
|
1755
|
+
if (!attrs.ngRequired && !value) {
|
1756
|
+
return true;
|
1757
|
+
}
|
1758
|
+
|
1589
1759
|
if (angular.isNumber(value)) {
|
1590
1760
|
value = new Date(value);
|
1591
1761
|
}
|
@@ -1594,7 +1764,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1594
1764
|
} else if (angular.isDate(value) && !isNaN(value)) {
|
1595
1765
|
return true;
|
1596
1766
|
} else if (angular.isString(value)) {
|
1597
|
-
var date = dateParser.parse(value, dateFormat)
|
1767
|
+
var date = dateParser.parse(value, dateFormat);
|
1598
1768
|
return !isNaN(date);
|
1599
1769
|
} else {
|
1600
1770
|
return false;
|
@@ -1623,7 +1793,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1623
1793
|
if (angular.isDefined(dt)) {
|
1624
1794
|
scope.date = dt;
|
1625
1795
|
}
|
1626
|
-
var date = scope.date ? dateFilter(scope.date, dateFormat) :
|
1796
|
+
var date = scope.date ? dateFilter(scope.date, dateFormat) : null; // Setting to NULL is necessary for form validators to function
|
1627
1797
|
element.val(date);
|
1628
1798
|
ngModel.$setViewValue(date);
|
1629
1799
|
|
@@ -1635,41 +1805,53 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1635
1805
|
|
1636
1806
|
// Detect changes in the view from the text box
|
1637
1807
|
ngModel.$viewChangeListeners.push(function () {
|
1638
|
-
scope.date = dateParser.parse(ngModel.$viewValue, dateFormat, scope.date)
|
1808
|
+
scope.date = dateParser.parse(ngModel.$viewValue, dateFormat, scope.date);
|
1639
1809
|
});
|
1640
1810
|
|
1641
1811
|
var documentClickBind = function(event) {
|
1642
|
-
if (scope.isOpen &&
|
1812
|
+
if (scope.isOpen && !element[0].contains(event.target)) {
|
1643
1813
|
scope.$apply(function() {
|
1644
1814
|
scope.isOpen = false;
|
1645
1815
|
});
|
1646
1816
|
}
|
1647
1817
|
};
|
1648
1818
|
|
1649
|
-
var
|
1650
|
-
scope.
|
1819
|
+
var inputKeydownBind = function(evt) {
|
1820
|
+
if (evt.which === 27 && scope.isOpen) {
|
1821
|
+
evt.preventDefault();
|
1822
|
+
evt.stopPropagation();
|
1823
|
+
scope.$apply(function() {
|
1824
|
+
scope.isOpen = false;
|
1825
|
+
});
|
1826
|
+
element[0].focus();
|
1827
|
+
} else if (evt.which === 40 && !scope.isOpen) {
|
1828
|
+
evt.preventDefault();
|
1829
|
+
evt.stopPropagation();
|
1830
|
+
scope.$apply(function() {
|
1831
|
+
scope.isOpen = true;
|
1832
|
+
});
|
1833
|
+
}
|
1651
1834
|
};
|
1652
|
-
element.bind('keydown',
|
1835
|
+
element.bind('keydown', inputKeydownBind);
|
1653
1836
|
|
1654
1837
|
scope.keydown = function(evt) {
|
1655
1838
|
if (evt.which === 27) {
|
1656
|
-
|
1657
|
-
|
1658
|
-
evt.stopPropagation();
|
1659
|
-
}
|
1660
|
-
scope.close();
|
1661
|
-
} else if (evt.which === 40 && !scope.isOpen) {
|
1662
|
-
scope.isOpen = true;
|
1839
|
+
scope.isOpen = false;
|
1840
|
+
element[0].focus();
|
1663
1841
|
}
|
1664
1842
|
};
|
1665
1843
|
|
1666
1844
|
scope.$watch('isOpen', function(value) {
|
1667
1845
|
if (value) {
|
1668
|
-
scope.$broadcast('datepicker.focus');
|
1669
1846
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
1670
1847
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
1671
1848
|
|
1672
|
-
$
|
1849
|
+
$timeout(function() {
|
1850
|
+
if (onOpenFocus) {
|
1851
|
+
scope.$broadcast('datepicker.focus');
|
1852
|
+
}
|
1853
|
+
$document.bind('click', documentClickBind);
|
1854
|
+
}, 0, false);
|
1673
1855
|
} else {
|
1674
1856
|
$document.unbind('click', documentClickBind);
|
1675
1857
|
}
|
@@ -1704,8 +1886,16 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1704
1886
|
}
|
1705
1887
|
|
1706
1888
|
scope.$on('$destroy', function() {
|
1889
|
+
if (scope.isOpen === true) {
|
1890
|
+
if (!$rootScope.$$phase) {
|
1891
|
+
scope.$apply(function() {
|
1892
|
+
scope.isOpen = false;
|
1893
|
+
});
|
1894
|
+
}
|
1895
|
+
}
|
1896
|
+
|
1707
1897
|
$popup.remove();
|
1708
|
-
element.unbind('keydown',
|
1898
|
+
element.unbind('keydown', inputKeydownBind);
|
1709
1899
|
$document.unbind('click', documentClickBind);
|
1710
1900
|
});
|
1711
1901
|
}
|
@@ -1717,12 +1907,8 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
|
|
1717
1907
|
restrict:'EA',
|
1718
1908
|
replace: true,
|
1719
1909
|
transclude: true,
|
1720
|
-
templateUrl:
|
1721
|
-
|
1722
|
-
element.bind('click', function(event) {
|
1723
|
-
event.preventDefault();
|
1724
|
-
event.stopPropagation();
|
1725
|
-
});
|
1910
|
+
templateUrl: function(element, attrs) {
|
1911
|
+
return attrs.templateUrl || 'template/datepicker/popup.html';
|
1726
1912
|
}
|
1727
1913
|
};
|
1728
1914
|
});
|
@@ -1739,11 +1925,11 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1739
1925
|
this.open = function( dropdownScope ) {
|
1740
1926
|
if ( !openScope ) {
|
1741
1927
|
$document.bind('click', closeDropdown);
|
1742
|
-
$document.bind('keydown',
|
1928
|
+
$document.bind('keydown', keybindFilter);
|
1743
1929
|
}
|
1744
1930
|
|
1745
1931
|
if ( openScope && openScope !== dropdownScope ) {
|
1746
|
-
|
1932
|
+
openScope.isOpen = false;
|
1747
1933
|
}
|
1748
1934
|
|
1749
1935
|
openScope = dropdownScope;
|
@@ -1753,7 +1939,7 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1753
1939
|
if ( openScope === dropdownScope ) {
|
1754
1940
|
openScope = null;
|
1755
1941
|
$document.unbind('click', closeDropdown);
|
1756
|
-
$document.unbind('keydown',
|
1942
|
+
$document.unbind('keydown', keybindFilter);
|
1757
1943
|
}
|
1758
1944
|
};
|
1759
1945
|
|
@@ -1766,11 +1952,12 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1766
1952
|
|
1767
1953
|
var toggleElement = openScope.getToggleElement();
|
1768
1954
|
if ( evt && toggleElement && toggleElement[0].contains(evt.target) ) {
|
1769
|
-
|
1955
|
+
return;
|
1770
1956
|
}
|
1771
1957
|
|
1772
|
-
var
|
1773
|
-
if(
|
1958
|
+
var dropdownElement = openScope.getDropdownElement();
|
1959
|
+
if (evt && openScope.getAutoClose() === 'outsideClick' &&
|
1960
|
+
dropdownElement && dropdownElement[0].contains(evt.target)) {
|
1774
1961
|
return;
|
1775
1962
|
}
|
1776
1963
|
|
@@ -1781,22 +1968,30 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1781
1968
|
}
|
1782
1969
|
};
|
1783
1970
|
|
1784
|
-
var
|
1971
|
+
var keybindFilter = function( evt ) {
|
1785
1972
|
if ( evt.which === 27 ) {
|
1786
1973
|
openScope.focusToggleElement();
|
1787
1974
|
closeDropdown();
|
1788
1975
|
}
|
1976
|
+
else if ( openScope.isKeynavEnabled() && /(38|40)/.test(evt.which) && openScope.isOpen ) {
|
1977
|
+
evt.preventDefault();
|
1978
|
+
evt.stopPropagation();
|
1979
|
+
openScope.focusDropdownEntry(evt.which);
|
1980
|
+
}
|
1789
1981
|
};
|
1790
1982
|
}])
|
1791
1983
|
|
1792
|
-
.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document) {
|
1984
|
+
.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', '$compile', '$templateRequest', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document, $compile, $templateRequest) {
|
1793
1985
|
var self = this,
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1986
|
+
scope = $scope.$new(), // create a child scope so we are not polluting original one
|
1987
|
+
templateScope,
|
1988
|
+
openClass = dropdownConfig.openClass,
|
1989
|
+
getIsOpen,
|
1990
|
+
setIsOpen = angular.noop,
|
1991
|
+
toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop,
|
1992
|
+
appendToBody = false,
|
1993
|
+
keynavEnabled =false,
|
1994
|
+
selectedOption = null;
|
1800
1995
|
|
1801
1996
|
this.init = function( element ) {
|
1802
1997
|
self.$element = element;
|
@@ -1811,6 +2006,7 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1811
2006
|
}
|
1812
2007
|
|
1813
2008
|
appendToBody = angular.isDefined($attrs.dropdownAppendToBody);
|
2009
|
+
keynavEnabled = angular.isDefined($attrs.keyboardNav);
|
1814
2010
|
|
1815
2011
|
if ( appendToBody && self.dropdownMenu ) {
|
1816
2012
|
$document.find('body').append( self.dropdownMenu );
|
@@ -1841,6 +2037,44 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1841
2037
|
return self.$element;
|
1842
2038
|
};
|
1843
2039
|
|
2040
|
+
scope.isKeynavEnabled = function() {
|
2041
|
+
return keynavEnabled;
|
2042
|
+
};
|
2043
|
+
|
2044
|
+
scope.focusDropdownEntry = function(keyCode) {
|
2045
|
+
var elems = self.dropdownMenu ? //If append to body is used.
|
2046
|
+
(angular.element(self.dropdownMenu).find('a')) :
|
2047
|
+
(angular.element(self.$element).find('ul').eq(0).find('a'));
|
2048
|
+
|
2049
|
+
switch (keyCode) {
|
2050
|
+
case (40): {
|
2051
|
+
if ( !angular.isNumber(self.selectedOption)) {
|
2052
|
+
self.selectedOption = 0;
|
2053
|
+
} else {
|
2054
|
+
self.selectedOption = (self.selectedOption === elems.length -1 ?
|
2055
|
+
self.selectedOption :
|
2056
|
+
self.selectedOption + 1);
|
2057
|
+
}
|
2058
|
+
break;
|
2059
|
+
}
|
2060
|
+
case (38): {
|
2061
|
+
if ( !angular.isNumber(self.selectedOption)) {
|
2062
|
+
return;
|
2063
|
+
} else {
|
2064
|
+
self.selectedOption = (self.selectedOption === 0 ?
|
2065
|
+
0 :
|
2066
|
+
self.selectedOption - 1);
|
2067
|
+
}
|
2068
|
+
break;
|
2069
|
+
}
|
2070
|
+
}
|
2071
|
+
elems[self.selectedOption].focus();
|
2072
|
+
};
|
2073
|
+
|
2074
|
+
scope.getDropdownElement = function() {
|
2075
|
+
return self.dropdownMenu;
|
2076
|
+
};
|
2077
|
+
|
1844
2078
|
scope.focusToggleElement = function() {
|
1845
2079
|
if ( self.toggleElement ) {
|
1846
2080
|
self.toggleElement[0].focus();
|
@@ -1848,32 +2082,68 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1848
2082
|
};
|
1849
2083
|
|
1850
2084
|
scope.$watch('isOpen', function( isOpen, wasOpen ) {
|
1851
|
-
if (
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
2085
|
+
if (appendToBody && self.dropdownMenu) {
|
2086
|
+
var pos = $position.positionElements(self.$element, self.dropdownMenu, 'bottom-left', true);
|
2087
|
+
var css = {
|
2088
|
+
top: pos.top + 'px',
|
2089
|
+
display: isOpen ? 'block' : 'none'
|
2090
|
+
};
|
2091
|
+
|
2092
|
+
var rightalign = self.dropdownMenu.hasClass('dropdown-menu-right');
|
2093
|
+
if (!rightalign) {
|
2094
|
+
css.left = pos.left + 'px';
|
2095
|
+
css.right = 'auto';
|
2096
|
+
} else {
|
2097
|
+
css.left = 'auto';
|
2098
|
+
css.right = (window.innerWidth - (pos.left + self.$element.prop('offsetWidth'))) + 'px';
|
2099
|
+
}
|
2100
|
+
|
2101
|
+
self.dropdownMenu.css(css);
|
1858
2102
|
}
|
1859
2103
|
|
1860
|
-
$animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass)
|
2104
|
+
$animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass).then(function() {
|
2105
|
+
if (angular.isDefined(isOpen) && isOpen !== wasOpen) {
|
2106
|
+
toggleInvoker($scope, { open: !!isOpen });
|
2107
|
+
}
|
2108
|
+
});
|
1861
2109
|
|
1862
2110
|
if ( isOpen ) {
|
2111
|
+
if (self.dropdownMenuTemplateUrl) {
|
2112
|
+
$templateRequest(self.dropdownMenuTemplateUrl).then(function(tplContent) {
|
2113
|
+
templateScope = scope.$new();
|
2114
|
+
$compile(tplContent.trim())(templateScope, function(dropdownElement) {
|
2115
|
+
var newEl = dropdownElement;
|
2116
|
+
self.dropdownMenu.replaceWith(newEl);
|
2117
|
+
self.dropdownMenu = newEl;
|
2118
|
+
});
|
2119
|
+
});
|
2120
|
+
}
|
2121
|
+
|
1863
2122
|
scope.focusToggleElement();
|
1864
2123
|
dropdownService.open( scope );
|
1865
2124
|
} else {
|
2125
|
+
if (self.dropdownMenuTemplateUrl) {
|
2126
|
+
if (templateScope) {
|
2127
|
+
templateScope.$destroy();
|
2128
|
+
}
|
2129
|
+
var newEl = angular.element('<ul class="dropdown-menu"></ul>');
|
2130
|
+
self.dropdownMenu.replaceWith(newEl);
|
2131
|
+
self.dropdownMenu = newEl;
|
2132
|
+
}
|
2133
|
+
|
1866
2134
|
dropdownService.close( scope );
|
2135
|
+
self.selectedOption = null;
|
1867
2136
|
}
|
1868
2137
|
|
1869
|
-
setIsOpen
|
1870
|
-
|
1871
|
-
toggleInvoker($scope, { open: !!isOpen });
|
2138
|
+
if (angular.isFunction(setIsOpen)) {
|
2139
|
+
setIsOpen($scope, isOpen);
|
1872
2140
|
}
|
1873
2141
|
});
|
1874
2142
|
|
1875
2143
|
$scope.$on('$locationChangeSuccess', function() {
|
1876
|
-
scope.
|
2144
|
+
if (scope.getAutoClose() !== 'disabled') {
|
2145
|
+
scope.isOpen = false;
|
2146
|
+
}
|
1877
2147
|
});
|
1878
2148
|
|
1879
2149
|
$scope.$on('$destroy', function() {
|
@@ -1886,6 +2156,7 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1886
2156
|
controller: 'DropdownController',
|
1887
2157
|
link: function(scope, element, attrs, dropdownCtrl) {
|
1888
2158
|
dropdownCtrl.init( element );
|
2159
|
+
element.addClass('dropdown');
|
1889
2160
|
}
|
1890
2161
|
};
|
1891
2162
|
})
|
@@ -1895,11 +2166,55 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1895
2166
|
restrict: 'AC',
|
1896
2167
|
require: '?^dropdown',
|
1897
2168
|
link: function(scope, element, attrs, dropdownCtrl) {
|
1898
|
-
if (
|
2169
|
+
if (!dropdownCtrl) {
|
1899
2170
|
return;
|
1900
2171
|
}
|
1901
|
-
|
2172
|
+
var tplUrl = attrs.templateUrl;
|
2173
|
+
if (tplUrl) {
|
2174
|
+
dropdownCtrl.dropdownMenuTemplateUrl = tplUrl;
|
2175
|
+
}
|
2176
|
+
if (!dropdownCtrl.dropdownMenu) {
|
2177
|
+
dropdownCtrl.dropdownMenu = element;
|
2178
|
+
}
|
2179
|
+
}
|
2180
|
+
};
|
2181
|
+
})
|
2182
|
+
|
2183
|
+
.directive('keyboardNav', function() {
|
2184
|
+
return {
|
2185
|
+
restrict: 'A',
|
2186
|
+
require: '?^dropdown',
|
2187
|
+
link: function (scope, element, attrs, dropdownCtrl) {
|
2188
|
+
|
2189
|
+
element.bind('keydown', function(e) {
|
2190
|
+
|
2191
|
+
if ([38, 40].indexOf(e.which) !== -1) {
|
2192
|
+
|
2193
|
+
e.preventDefault();
|
2194
|
+
e.stopPropagation();
|
2195
|
+
|
2196
|
+
var elems = dropdownCtrl.dropdownMenu.find('a');
|
2197
|
+
|
2198
|
+
switch (e.which) {
|
2199
|
+
case (40): { // Down
|
2200
|
+
if ( !angular.isNumber(dropdownCtrl.selectedOption)) {
|
2201
|
+
dropdownCtrl.selectedOption = 0;
|
2202
|
+
} else {
|
2203
|
+
dropdownCtrl.selectedOption = (dropdownCtrl.selectedOption === elems.length -1 ? dropdownCtrl.selectedOption : dropdownCtrl.selectedOption+1);
|
2204
|
+
}
|
2205
|
+
|
2206
|
+
}
|
2207
|
+
break;
|
2208
|
+
case (38): { // Up
|
2209
|
+
dropdownCtrl.selectedOption = (dropdownCtrl.selectedOption === 0 ? 0 : dropdownCtrl.selectedOption-1);
|
2210
|
+
}
|
2211
|
+
break;
|
2212
|
+
}
|
2213
|
+
elems[dropdownCtrl.selectedOption].focus();
|
2214
|
+
}
|
2215
|
+
});
|
1902
2216
|
}
|
2217
|
+
|
1903
2218
|
};
|
1904
2219
|
})
|
1905
2220
|
|
@@ -1911,6 +2226,8 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
|
|
1911
2226
|
return;
|
1912
2227
|
}
|
1913
2228
|
|
2229
|
+
element.addClass('dropdown-toggle');
|
2230
|
+
|
1914
2231
|
dropdownCtrl.toggleElement = element;
|
1915
2232
|
|
1916
2233
|
var toggleDropdown = function(event) {
|
@@ -1997,7 +2314,15 @@ angular.module('ui.bootstrap.modal', [])
|
|
1997
2314
|
/**
|
1998
2315
|
* A helper directive for the $modal service. It creates a backdrop element.
|
1999
2316
|
*/
|
2000
|
-
.directive('modalBackdrop', [
|
2317
|
+
.directive('modalBackdrop', [
|
2318
|
+
'$animate', '$injector', '$modalStack',
|
2319
|
+
function ($animate , $injector, $modalStack) {
|
2320
|
+
var $animateCss = null;
|
2321
|
+
|
2322
|
+
if ($injector.has('$animateCss')) {
|
2323
|
+
$animateCss = $injector.get('$animateCss');
|
2324
|
+
}
|
2325
|
+
|
2001
2326
|
return {
|
2002
2327
|
restrict: 'EA',
|
2003
2328
|
replace: true,
|
@@ -2009,21 +2334,42 @@ angular.module('ui.bootstrap.modal', [])
|
|
2009
2334
|
};
|
2010
2335
|
|
2011
2336
|
function linkFn(scope, element, attrs) {
|
2012
|
-
|
2337
|
+
if (attrs.modalInClass) {
|
2338
|
+
if ($animateCss) {
|
2339
|
+
$animateCss(element, {
|
2340
|
+
addClass: attrs.modalInClass
|
2341
|
+
}).start();
|
2342
|
+
} else {
|
2343
|
+
$animate.addClass(element, attrs.modalInClass);
|
2344
|
+
}
|
2013
2345
|
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2346
|
+
scope.$on($modalStack.NOW_CLOSING_EVENT, function (e, setIsAsync) {
|
2347
|
+
var done = setIsAsync();
|
2348
|
+
if ($animateCss) {
|
2349
|
+
$animateCss(element, {
|
2350
|
+
removeClass: attrs.modalInClass
|
2351
|
+
}).start().then(done);
|
2352
|
+
} else {
|
2353
|
+
$animate.removeClass(element, attrs.modalInClass).then(done);
|
2354
|
+
}
|
2355
|
+
});
|
2356
|
+
}
|
2018
2357
|
}
|
2019
2358
|
}])
|
2020
2359
|
|
2021
|
-
.directive('modalWindow', [
|
2360
|
+
.directive('modalWindow', [
|
2361
|
+
'$modalStack', '$q', '$animate', '$injector',
|
2362
|
+
function ($modalStack , $q , $animate, $injector) {
|
2363
|
+
var $animateCss = null;
|
2364
|
+
|
2365
|
+
if ($injector.has('$animateCss')) {
|
2366
|
+
$animateCss = $injector.get('$animateCss');
|
2367
|
+
}
|
2368
|
+
|
2022
2369
|
return {
|
2023
2370
|
restrict: 'EA',
|
2024
2371
|
scope: {
|
2025
|
-
index: '@'
|
2026
|
-
animate: '='
|
2372
|
+
index: '@'
|
2027
2373
|
},
|
2028
2374
|
replace: true,
|
2029
2375
|
transclude: true,
|
@@ -2059,8 +2405,26 @@ angular.module('ui.bootstrap.modal', [])
|
|
2059
2405
|
});
|
2060
2406
|
|
2061
2407
|
modalRenderDeferObj.promise.then(function () {
|
2062
|
-
|
2063
|
-
|
2408
|
+
if (attrs.modalInClass) {
|
2409
|
+
if ($animateCss) {
|
2410
|
+
$animateCss(element, {
|
2411
|
+
addClass: attrs.modalInClass
|
2412
|
+
}).start();
|
2413
|
+
} else {
|
2414
|
+
$animate.addClass(element, attrs.modalInClass);
|
2415
|
+
}
|
2416
|
+
|
2417
|
+
scope.$on($modalStack.NOW_CLOSING_EVENT, function (e, setIsAsync) {
|
2418
|
+
var done = setIsAsync();
|
2419
|
+
if ($animateCss) {
|
2420
|
+
$animateCss(element, {
|
2421
|
+
removeClass: attrs.modalInClass
|
2422
|
+
}).start().then(done);
|
2423
|
+
} else {
|
2424
|
+
$animate.removeClass(element, attrs.modalInClass).then(done);
|
2425
|
+
}
|
2426
|
+
});
|
2427
|
+
}
|
2064
2428
|
|
2065
2429
|
var inputsWithAutofocus = element[0].querySelectorAll('[autofocus]');
|
2066
2430
|
/**
|
@@ -2109,14 +2473,35 @@ angular.module('ui.bootstrap.modal', [])
|
|
2109
2473
|
};
|
2110
2474
|
})
|
2111
2475
|
|
2112
|
-
.factory('$modalStack', [
|
2113
|
-
|
2476
|
+
.factory('$modalStack', [
|
2477
|
+
'$animate', '$timeout', '$document', '$compile', '$rootScope',
|
2478
|
+
'$q',
|
2479
|
+
'$injector',
|
2480
|
+
'$$stackedMap',
|
2481
|
+
function ($animate , $timeout , $document , $compile , $rootScope ,
|
2482
|
+
$q,
|
2483
|
+
$injector,
|
2484
|
+
$$stackedMap) {
|
2485
|
+
var $animateCss = null;
|
2486
|
+
|
2487
|
+
if ($injector.has('$animateCss')) {
|
2488
|
+
$animateCss = $injector.get('$animateCss');
|
2489
|
+
}
|
2114
2490
|
|
2115
2491
|
var OPENED_MODAL_CLASS = 'modal-open';
|
2116
2492
|
|
2117
2493
|
var backdropDomEl, backdropScope;
|
2118
2494
|
var openedWindows = $$stackedMap.createNew();
|
2119
|
-
var $modalStack = {
|
2495
|
+
var $modalStack = {
|
2496
|
+
NOW_CLOSING_EVENT: 'modal.stack.now-closing'
|
2497
|
+
};
|
2498
|
+
|
2499
|
+
//Modal focus behavior
|
2500
|
+
var focusableElementList;
|
2501
|
+
var focusIndex = 0;
|
2502
|
+
var tababbleSelector = 'a[href], area[href], input:not([disabled]), ' +
|
2503
|
+
'button:not([disabled]),select:not([disabled]), textarea:not([disabled]), ' +
|
2504
|
+
'iframe, object, embed, *[tabindex], *[contenteditable=true]';
|
2120
2505
|
|
2121
2506
|
function backdropIndex() {
|
2122
2507
|
var topBackdropIndex = -1;
|
@@ -2129,13 +2514,13 @@ angular.module('ui.bootstrap.modal', [])
|
|
2129
2514
|
return topBackdropIndex;
|
2130
2515
|
}
|
2131
2516
|
|
2132
|
-
$rootScope.$watch(backdropIndex, function(newBackdropIndex){
|
2517
|
+
$rootScope.$watch(backdropIndex, function(newBackdropIndex) {
|
2133
2518
|
if (backdropScope) {
|
2134
2519
|
backdropScope.index = newBackdropIndex;
|
2135
2520
|
}
|
2136
2521
|
});
|
2137
2522
|
|
2138
|
-
function removeModalWindow(modalInstance) {
|
2523
|
+
function removeModalWindow(modalInstance, elementToReceiveFocus) {
|
2139
2524
|
|
2140
2525
|
var body = $document.find('body').eq(0);
|
2141
2526
|
var modalWindow = openedWindows.get(modalInstance).value;
|
@@ -2143,11 +2528,17 @@ angular.module('ui.bootstrap.modal', [])
|
|
2143
2528
|
//clean up the stack
|
2144
2529
|
openedWindows.remove(modalInstance);
|
2145
2530
|
|
2146
|
-
//remove window DOM element
|
2147
2531
|
removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, function() {
|
2148
|
-
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
|
2149
|
-
checkRemoveBackdrop();
|
2532
|
+
body.toggleClass(modalInstance.openedClass || OPENED_MODAL_CLASS, openedWindows.length() > 0);
|
2150
2533
|
});
|
2534
|
+
checkRemoveBackdrop();
|
2535
|
+
|
2536
|
+
//move focus to specified element if available, or else to body
|
2537
|
+
if (elementToReceiveFocus && elementToReceiveFocus.focus) {
|
2538
|
+
elementToReceiveFocus.focus();
|
2539
|
+
} else {
|
2540
|
+
body.focus();
|
2541
|
+
}
|
2151
2542
|
}
|
2152
2543
|
|
2153
2544
|
function checkRemoveBackdrop() {
|
@@ -2163,18 +2554,24 @@ angular.module('ui.bootstrap.modal', [])
|
|
2163
2554
|
}
|
2164
2555
|
|
2165
2556
|
function removeAfterAnimate(domEl, scope, done) {
|
2166
|
-
|
2167
|
-
|
2557
|
+
var asyncDeferred;
|
2558
|
+
var asyncPromise = null;
|
2559
|
+
var setIsAsync = function () {
|
2560
|
+
if (!asyncDeferred) {
|
2561
|
+
asyncDeferred = $q.defer();
|
2562
|
+
asyncPromise = asyncDeferred.promise;
|
2563
|
+
}
|
2168
2564
|
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2565
|
+
return function asyncDone() {
|
2566
|
+
asyncDeferred.resolve();
|
2567
|
+
};
|
2568
|
+
};
|
2569
|
+
scope.$broadcast($modalStack.NOW_CLOSING_EVENT, setIsAsync);
|
2570
|
+
|
2571
|
+
// Note that it's intentional that asyncPromise might be null.
|
2572
|
+
// That's when setIsAsync has not been called during the
|
2573
|
+
// NOW_CLOSING_EVENT broadcast.
|
2574
|
+
return $q.when(asyncPromise).then(afterAnimating);
|
2178
2575
|
|
2179
2576
|
function afterAnimating() {
|
2180
2577
|
if (afterAnimating.done) {
|
@@ -2182,7 +2579,15 @@ angular.module('ui.bootstrap.modal', [])
|
|
2182
2579
|
}
|
2183
2580
|
afterAnimating.done = true;
|
2184
2581
|
|
2185
|
-
|
2582
|
+
if ($animateCss) {
|
2583
|
+
$animateCss(domEl, {
|
2584
|
+
event: 'leave'
|
2585
|
+
}).start().then(function() {
|
2586
|
+
domEl.remove();
|
2587
|
+
});
|
2588
|
+
} else {
|
2589
|
+
$animate.leave(domEl);
|
2590
|
+
}
|
2186
2591
|
scope.$destroy();
|
2187
2592
|
if (done) {
|
2188
2593
|
done();
|
@@ -2191,15 +2596,39 @@ angular.module('ui.bootstrap.modal', [])
|
|
2191
2596
|
}
|
2192
2597
|
|
2193
2598
|
$document.bind('keydown', function (evt) {
|
2194
|
-
|
2599
|
+
if (evt.isDefaultPrevented()) {
|
2600
|
+
return evt;
|
2601
|
+
}
|
2195
2602
|
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
$
|
2202
|
-
|
2603
|
+
var modal = openedWindows.top();
|
2604
|
+
if (modal && modal.value.keyboard) {
|
2605
|
+
switch (evt.which){
|
2606
|
+
case 27: {
|
2607
|
+
evt.preventDefault();
|
2608
|
+
$rootScope.$apply(function () {
|
2609
|
+
$modalStack.dismiss(modal.key, 'escape key press');
|
2610
|
+
});
|
2611
|
+
break;
|
2612
|
+
}
|
2613
|
+
case 9: {
|
2614
|
+
$modalStack.loadFocusElementList(modal);
|
2615
|
+
var focusChanged = false;
|
2616
|
+
if (evt.shiftKey) {
|
2617
|
+
if ($modalStack.isFocusInFirstItem(evt)) {
|
2618
|
+
focusChanged = $modalStack.focusLastFocusableElement();
|
2619
|
+
}
|
2620
|
+
} else {
|
2621
|
+
if ($modalStack.isFocusInLastItem(evt)) {
|
2622
|
+
focusChanged = $modalStack.focusFirstFocusableElement();
|
2623
|
+
}
|
2624
|
+
}
|
2625
|
+
|
2626
|
+
if (focusChanged) {
|
2627
|
+
evt.preventDefault();
|
2628
|
+
evt.stopPropagation();
|
2629
|
+
}
|
2630
|
+
break;
|
2631
|
+
}
|
2203
2632
|
}
|
2204
2633
|
}
|
2205
2634
|
});
|
@@ -2213,7 +2642,8 @@ angular.module('ui.bootstrap.modal', [])
|
|
2213
2642
|
renderDeferred: modal.renderDeferred,
|
2214
2643
|
modalScope: modal.scope,
|
2215
2644
|
backdrop: modal.backdrop,
|
2216
|
-
keyboard: modal.keyboard
|
2645
|
+
keyboard: modal.keyboard,
|
2646
|
+
openedClass: modal.openedClass
|
2217
2647
|
});
|
2218
2648
|
|
2219
2649
|
var body = $document.find('body').eq(0),
|
@@ -2247,7 +2677,8 @@ angular.module('ui.bootstrap.modal', [])
|
|
2247
2677
|
openedWindows.top().value.modalDomEl = modalDomEl;
|
2248
2678
|
openedWindows.top().value.modalOpener = modalOpener;
|
2249
2679
|
body.append(modalDomEl);
|
2250
|
-
body.addClass(OPENED_MODAL_CLASS);
|
2680
|
+
body.addClass(modal.openedClass || OPENED_MODAL_CLASS);
|
2681
|
+
$modalStack.clearFocusListCache();
|
2251
2682
|
};
|
2252
2683
|
|
2253
2684
|
function broadcastClosing(modalWindow, resultOrReason, closing) {
|
@@ -2257,9 +2688,9 @@ angular.module('ui.bootstrap.modal', [])
|
|
2257
2688
|
$modalStack.close = function (modalInstance, result) {
|
2258
2689
|
var modalWindow = openedWindows.get(modalInstance);
|
2259
2690
|
if (modalWindow && broadcastClosing(modalWindow, result, true)) {
|
2691
|
+
modalWindow.value.modalScope.$$uibDestructionScheduled = true;
|
2260
2692
|
modalWindow.value.deferred.resolve(result);
|
2261
|
-
removeModalWindow(modalInstance);
|
2262
|
-
modalWindow.value.modalOpener.focus();
|
2693
|
+
removeModalWindow(modalInstance, modalWindow.value.modalOpener);
|
2263
2694
|
return true;
|
2264
2695
|
}
|
2265
2696
|
return !modalWindow;
|
@@ -2268,9 +2699,9 @@ angular.module('ui.bootstrap.modal', [])
|
|
2268
2699
|
$modalStack.dismiss = function (modalInstance, reason) {
|
2269
2700
|
var modalWindow = openedWindows.get(modalInstance);
|
2270
2701
|
if (modalWindow && broadcastClosing(modalWindow, reason, false)) {
|
2702
|
+
modalWindow.value.modalScope.$$uibDestructionScheduled = true;
|
2271
2703
|
modalWindow.value.deferred.reject(reason);
|
2272
|
-
removeModalWindow(modalInstance);
|
2273
|
-
modalWindow.value.modalOpener.focus();
|
2704
|
+
removeModalWindow(modalInstance, modalWindow.value.modalOpener);
|
2274
2705
|
return true;
|
2275
2706
|
}
|
2276
2707
|
return !modalWindow;
|
@@ -2294,6 +2725,51 @@ angular.module('ui.bootstrap.modal', [])
|
|
2294
2725
|
}
|
2295
2726
|
};
|
2296
2727
|
|
2728
|
+
$modalStack.focusFirstFocusableElement = function() {
|
2729
|
+
if (focusableElementList.length > 0) {
|
2730
|
+
focusableElementList[0].focus();
|
2731
|
+
return true;
|
2732
|
+
}
|
2733
|
+
return false;
|
2734
|
+
};
|
2735
|
+
$modalStack.focusLastFocusableElement = function() {
|
2736
|
+
if (focusableElementList.length > 0) {
|
2737
|
+
focusableElementList[focusableElementList.length - 1].focus();
|
2738
|
+
return true;
|
2739
|
+
}
|
2740
|
+
return false;
|
2741
|
+
};
|
2742
|
+
|
2743
|
+
$modalStack.isFocusInFirstItem = function(evt) {
|
2744
|
+
if (focusableElementList.length > 0) {
|
2745
|
+
return (evt.target || evt.srcElement) == focusableElementList[0];
|
2746
|
+
}
|
2747
|
+
return false;
|
2748
|
+
};
|
2749
|
+
|
2750
|
+
$modalStack.isFocusInLastItem = function(evt) {
|
2751
|
+
if (focusableElementList.length > 0) {
|
2752
|
+
return (evt.target || evt.srcElement) == focusableElementList[focusableElementList.length - 1];
|
2753
|
+
}
|
2754
|
+
return false;
|
2755
|
+
};
|
2756
|
+
|
2757
|
+
$modalStack.clearFocusListCache = function() {
|
2758
|
+
focusableElementList = [];
|
2759
|
+
focusIndex = 0;
|
2760
|
+
};
|
2761
|
+
|
2762
|
+
$modalStack.loadFocusElementList = function(modalWindow) {
|
2763
|
+
if (focusableElementList === undefined || !focusableElementList.length0) {
|
2764
|
+
if (modalWindow) {
|
2765
|
+
var modalDomE1 = modalWindow.value.modalDomEl;
|
2766
|
+
if (modalDomE1 && modalDomE1.length) {
|
2767
|
+
focusableElementList = modalDomE1[0].querySelectorAll(tababbleSelector);
|
2768
|
+
}
|
2769
|
+
}
|
2770
|
+
}
|
2771
|
+
};
|
2772
|
+
|
2297
2773
|
return $modalStack;
|
2298
2774
|
}])
|
2299
2775
|
|
@@ -2320,6 +2796,8 @@ angular.module('ui.bootstrap.modal', [])
|
|
2320
2796
|
angular.forEach(resolves, function (value) {
|
2321
2797
|
if (angular.isFunction(value) || angular.isArray(value)) {
|
2322
2798
|
promisesArr.push($q.when($injector.invoke(value)));
|
2799
|
+
} else if (angular.isString(value)) {
|
2800
|
+
promisesArr.push($q.when($injector.get(value)));
|
2323
2801
|
}
|
2324
2802
|
});
|
2325
2803
|
return promisesArr;
|
@@ -2363,6 +2841,12 @@ angular.module('ui.bootstrap.modal', [])
|
|
2363
2841
|
modalScope.$close = modalInstance.close;
|
2364
2842
|
modalScope.$dismiss = modalInstance.dismiss;
|
2365
2843
|
|
2844
|
+
modalScope.$on('$destroy', function() {
|
2845
|
+
if (!modalScope.$$uibDestructionScheduled) {
|
2846
|
+
modalScope.$dismiss('$uibUnscheduledDestruction');
|
2847
|
+
}
|
2848
|
+
});
|
2849
|
+
|
2366
2850
|
var ctrlInstance, ctrlLocals = {};
|
2367
2851
|
var resolveIter = 1;
|
2368
2852
|
|
@@ -2376,6 +2860,10 @@ angular.module('ui.bootstrap.modal', [])
|
|
2376
2860
|
|
2377
2861
|
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
|
2378
2862
|
if (modalOptions.controllerAs) {
|
2863
|
+
if (modalOptions.bindToController) {
|
2864
|
+
angular.extend(ctrlInstance, modalScope);
|
2865
|
+
}
|
2866
|
+
|
2379
2867
|
modalScope[modalOptions.controllerAs] = ctrlInstance;
|
2380
2868
|
}
|
2381
2869
|
}
|
@@ -2391,7 +2879,8 @@ angular.module('ui.bootstrap.modal', [])
|
|
2391
2879
|
backdropClass: modalOptions.backdropClass,
|
2392
2880
|
windowClass: modalOptions.windowClass,
|
2393
2881
|
windowTemplateUrl: modalOptions.windowTemplateUrl,
|
2394
|
-
size: modalOptions.size
|
2882
|
+
size: modalOptions.size,
|
2883
|
+
openedClass: modalOptions.openedClass
|
2395
2884
|
});
|
2396
2885
|
|
2397
2886
|
}, function resolveError(reason) {
|
@@ -2415,7 +2904,6 @@ angular.module('ui.bootstrap.modal', [])
|
|
2415
2904
|
});
|
2416
2905
|
|
2417
2906
|
angular.module('ui.bootstrap.pagination', [])
|
2418
|
-
|
2419
2907
|
.controller('PaginationController', ['$scope', '$attrs', '$parse', function ($scope, $attrs, $parse) {
|
2420
2908
|
var self = this,
|
2421
2909
|
ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
|
@@ -2463,7 +2951,12 @@ angular.module('ui.bootstrap.pagination', [])
|
|
2463
2951
|
};
|
2464
2952
|
|
2465
2953
|
$scope.selectPage = function(page, evt) {
|
2466
|
-
if (
|
2954
|
+
if (evt) {
|
2955
|
+
evt.preventDefault();
|
2956
|
+
}
|
2957
|
+
|
2958
|
+
var clickAllowed = !$scope.ngDisabled || !evt;
|
2959
|
+
if (clickAllowed && $scope.page !== page && page > 0 && page <= $scope.totalPages) {
|
2467
2960
|
if (evt && evt.target) {
|
2468
2961
|
evt.target.blur();
|
2469
2962
|
}
|
@@ -2502,11 +2995,15 @@ angular.module('ui.bootstrap.pagination', [])
|
|
2502
2995
|
firstText: '@',
|
2503
2996
|
previousText: '@',
|
2504
2997
|
nextText: '@',
|
2505
|
-
lastText: '@'
|
2998
|
+
lastText: '@',
|
2999
|
+
ngDisabled:'='
|
2506
3000
|
},
|
2507
3001
|
require: ['pagination', '?ngModel'],
|
2508
3002
|
controller: 'PaginationController',
|
2509
|
-
|
3003
|
+
controllerAs: 'pagination',
|
3004
|
+
templateUrl: function(element, attrs) {
|
3005
|
+
return attrs.templateUrl || 'template/pagination/pagination.html';
|
3006
|
+
},
|
2510
3007
|
replace: true,
|
2511
3008
|
link: function(scope, element, attrs, ctrls) {
|
2512
3009
|
var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
@@ -2699,7 +3196,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2699
3196
|
* Returns the actual instance of the $tooltip service.
|
2700
3197
|
* TODO support multiple triggers
|
2701
3198
|
*/
|
2702
|
-
this.$get = [ '$window', '$compile', '$timeout', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $document, $position, $interpolate ) {
|
3199
|
+
this.$get = [ '$window', '$compile', '$timeout', '$document', '$position', '$interpolate', '$rootScope', function ( $window, $compile, $timeout, $document, $position, $interpolate, $rootScope ) {
|
2703
3200
|
return function $tooltip ( type, prefix, defaultTriggerShow, options ) {
|
2704
3201
|
options = angular.extend( {}, defaultOptions, globalOptions, options );
|
2705
3202
|
|
@@ -2718,8 +3215,10 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2718
3215
|
* trigger; else it will just use the show trigger.
|
2719
3216
|
*/
|
2720
3217
|
function getTriggers ( trigger ) {
|
2721
|
-
var show = trigger || options.trigger || defaultTriggerShow;
|
2722
|
-
var hide =
|
3218
|
+
var show = (trigger || options.trigger || defaultTriggerShow).split(' ');
|
3219
|
+
var hide = show.map(function(trigger) {
|
3220
|
+
return triggerMap[trigger] || trigger;
|
3221
|
+
});
|
2723
3222
|
return {
|
2724
3223
|
show: show,
|
2725
3224
|
hide: hide
|
@@ -2758,6 +3257,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2758
3257
|
var triggers = getTriggers( undefined );
|
2759
3258
|
var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
|
2760
3259
|
var ttScope = scope.$new(true);
|
3260
|
+
var repositionScheduled = false;
|
2761
3261
|
|
2762
3262
|
var positionTooltip = function () {
|
2763
3263
|
if (!tooltip) { return; }
|
@@ -2770,6 +3270,10 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2770
3270
|
tooltip.css( ttPosition );
|
2771
3271
|
};
|
2772
3272
|
|
3273
|
+
var positionTooltipAsync = function () {
|
3274
|
+
$timeout(positionTooltip, 0, false);
|
3275
|
+
};
|
3276
|
+
|
2773
3277
|
// Set up the correct scope to allow transclusion later
|
2774
3278
|
ttScope.origScope = scope;
|
2775
3279
|
|
@@ -2806,9 +3310,10 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2806
3310
|
}
|
2807
3311
|
|
2808
3312
|
function hideTooltipBind () {
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
3313
|
+
hide();
|
3314
|
+
if (!$rootScope.$$phase) {
|
3315
|
+
$rootScope.$digest();
|
3316
|
+
}
|
2812
3317
|
}
|
2813
3318
|
|
2814
3319
|
// Show the tooltip popup element.
|
@@ -2832,7 +3337,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2832
3337
|
|
2833
3338
|
// Set the initial positioning.
|
2834
3339
|
tooltip.css({ top: 0, left: 0, display: 'block' });
|
2835
|
-
ttScope.$digest();
|
2836
3340
|
|
2837
3341
|
positionTooltip();
|
2838
3342
|
|
@@ -2880,16 +3384,23 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2880
3384
|
}
|
2881
3385
|
});
|
2882
3386
|
|
2883
|
-
tooltipLinkedScope.$watch(function () {
|
2884
|
-
$timeout(positionTooltip, 0, false);
|
2885
|
-
});
|
2886
|
-
|
2887
3387
|
if (options.useContentExp) {
|
2888
3388
|
tooltipLinkedScope.$watch('contentExp()', function (val) {
|
2889
|
-
if (!val && ttScope.isOpen
|
3389
|
+
if (!val && ttScope.isOpen) {
|
2890
3390
|
hide();
|
2891
3391
|
}
|
2892
3392
|
});
|
3393
|
+
|
3394
|
+
tooltipLinkedScope.$watch(function() {
|
3395
|
+
if (!repositionScheduled) {
|
3396
|
+
repositionScheduled = true;
|
3397
|
+
tooltipLinkedScope.$$postDigest(function() {
|
3398
|
+
repositionScheduled = false;
|
3399
|
+
positionTooltipAsync();
|
3400
|
+
});
|
3401
|
+
}
|
3402
|
+
});
|
3403
|
+
|
2893
3404
|
}
|
2894
3405
|
}
|
2895
3406
|
|
@@ -2922,13 +3433,19 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2922
3433
|
attrs.$observe( type, function ( val ) {
|
2923
3434
|
ttScope.content = val;
|
2924
3435
|
|
2925
|
-
if (!val && ttScope.isOpen
|
3436
|
+
if (!val && ttScope.isOpen) {
|
2926
3437
|
hide();
|
3438
|
+
} else {
|
3439
|
+
positionTooltipAsync();
|
2927
3440
|
}
|
2928
3441
|
});
|
2929
3442
|
}
|
2930
3443
|
|
2931
3444
|
attrs.$observe( 'disabled', function ( val ) {
|
3445
|
+
if (popupTimeout && val) {
|
3446
|
+
$timeout.cancel(popupTimeout);
|
3447
|
+
}
|
3448
|
+
|
2932
3449
|
if (val && ttScope.isOpen ) {
|
2933
3450
|
hide();
|
2934
3451
|
}
|
@@ -2936,6 +3453,16 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2936
3453
|
|
2937
3454
|
attrs.$observe( prefix+'Title', function ( val ) {
|
2938
3455
|
ttScope.title = val;
|
3456
|
+
positionTooltipAsync();
|
3457
|
+
});
|
3458
|
+
|
3459
|
+
attrs.$observe( prefix + 'Placement', function () {
|
3460
|
+
if (ttScope.isOpen) {
|
3461
|
+
$timeout(function () {
|
3462
|
+
prepPlacement();
|
3463
|
+
show()();
|
3464
|
+
}, 0, false);
|
3465
|
+
}
|
2939
3466
|
});
|
2940
3467
|
|
2941
3468
|
function prepPopupClass() {
|
@@ -2954,8 +3481,12 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2954
3481
|
}
|
2955
3482
|
|
2956
3483
|
var unregisterTriggers = function () {
|
2957
|
-
|
2958
|
-
|
3484
|
+
triggers.show.forEach(function(trigger) {
|
3485
|
+
element.unbind(trigger, showTooltipBind);
|
3486
|
+
});
|
3487
|
+
triggers.hide.forEach(function(trigger) {
|
3488
|
+
element.unbind(trigger, hideTooltipBind);
|
3489
|
+
});
|
2959
3490
|
};
|
2960
3491
|
|
2961
3492
|
function prepTriggers() {
|
@@ -2964,12 +3495,14 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
|
|
2964
3495
|
|
2965
3496
|
triggers = getTriggers( val );
|
2966
3497
|
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
|
2971
|
-
|
2972
|
-
|
3498
|
+
triggers.show.forEach(function(trigger, idx) {
|
3499
|
+
if (trigger === triggers.hide[idx]) {
|
3500
|
+
element.bind(trigger, toggleTooltipBind);
|
3501
|
+
} else if (trigger) {
|
3502
|
+
element.bind(trigger, showTooltipBind);
|
3503
|
+
element.bind(triggers.hide[idx], hideTooltipBind);
|
3504
|
+
}
|
3505
|
+
});
|
2973
3506
|
}
|
2974
3507
|
prepTriggers();
|
2975
3508
|
|
@@ -3164,7 +3697,7 @@ function ( $tooltip , tooltipHtmlUnsafeSuppressDeprecated , $log) {
|
|
3164
3697
|
/**
|
3165
3698
|
* The following features are still outstanding: popup delay, animation as a
|
3166
3699
|
* function, placement as a function, inside, support for more triggers than
|
3167
|
-
* just mouse enter/leave,
|
3700
|
+
* just mouse enter/leave, and selector delegatation.
|
3168
3701
|
*/
|
3169
3702
|
angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
|
3170
3703
|
|
@@ -3184,6 +3717,21 @@ angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
|
|
3184
3717
|
} );
|
3185
3718
|
}])
|
3186
3719
|
|
3720
|
+
.directive( 'popoverHtmlPopup', function () {
|
3721
|
+
return {
|
3722
|
+
restrict: 'EA',
|
3723
|
+
replace: true,
|
3724
|
+
scope: { contentExp: '&', title: '@', placement: '@', popupClass: '@', animation: '&', isOpen: '&' },
|
3725
|
+
templateUrl: 'template/popover/popover-html.html'
|
3726
|
+
};
|
3727
|
+
})
|
3728
|
+
|
3729
|
+
.directive( 'popoverHtml', [ '$tooltip', function ( $tooltip ) {
|
3730
|
+
return $tooltip( 'popoverHtml', 'popover', 'click', {
|
3731
|
+
useContentExp: true
|
3732
|
+
});
|
3733
|
+
}])
|
3734
|
+
|
3187
3735
|
.directive( 'popoverPopup', function () {
|
3188
3736
|
return {
|
3189
3737
|
restrict: 'EA',
|
@@ -3218,10 +3766,25 @@ angular.module('ui.bootstrap.progressbar', [])
|
|
3218
3766
|
|
3219
3767
|
this.bars.push(bar);
|
3220
3768
|
|
3769
|
+
bar.max = $scope.max;
|
3770
|
+
|
3221
3771
|
bar.$watch('value', function( value ) {
|
3222
|
-
bar.
|
3772
|
+
bar.recalculatePercentage();
|
3223
3773
|
});
|
3224
3774
|
|
3775
|
+
bar.recalculatePercentage = function() {
|
3776
|
+
bar.percent = +(100 * bar.value / bar.max).toFixed(2);
|
3777
|
+
|
3778
|
+
var totalPercentage = 0;
|
3779
|
+
self.bars.forEach(function (bar) {
|
3780
|
+
totalPercentage += bar.percent;
|
3781
|
+
});
|
3782
|
+
|
3783
|
+
if (totalPercentage > 100) {
|
3784
|
+
bar.percent -= totalPercentage - 100;
|
3785
|
+
}
|
3786
|
+
};
|
3787
|
+
|
3225
3788
|
bar.$on('$destroy', function() {
|
3226
3789
|
element = null;
|
3227
3790
|
self.removeBar(bar);
|
@@ -3231,6 +3794,13 @@ angular.module('ui.bootstrap.progressbar', [])
|
|
3231
3794
|
this.removeBar = function(bar) {
|
3232
3795
|
this.bars.splice(this.bars.indexOf(bar), 1);
|
3233
3796
|
};
|
3797
|
+
|
3798
|
+
$scope.$watch('max', function(max) {
|
3799
|
+
self.bars.forEach(function (bar) {
|
3800
|
+
bar.max = $scope.max;
|
3801
|
+
bar.recalculatePercentage();
|
3802
|
+
});
|
3803
|
+
});
|
3234
3804
|
}])
|
3235
3805
|
|
3236
3806
|
.directive('progress', function() {
|
@@ -3240,7 +3810,9 @@ angular.module('ui.bootstrap.progressbar', [])
|
|
3240
3810
|
transclude: true,
|
3241
3811
|
controller: 'ProgressController',
|
3242
3812
|
require: 'progress',
|
3243
|
-
scope: {
|
3813
|
+
scope: {
|
3814
|
+
max: '=?'
|
3815
|
+
},
|
3244
3816
|
templateUrl: 'template/progressbar/progress.html'
|
3245
3817
|
};
|
3246
3818
|
})
|
@@ -3253,7 +3825,6 @@ angular.module('ui.bootstrap.progressbar', [])
|
|
3253
3825
|
require: '^progress',
|
3254
3826
|
scope: {
|
3255
3827
|
value: '=',
|
3256
|
-
max: '=?',
|
3257
3828
|
type: '@'
|
3258
3829
|
},
|
3259
3830
|
templateUrl: 'template/progressbar/bar.html',
|
@@ -3286,7 +3857,8 @@ angular.module('ui.bootstrap.rating', [])
|
|
3286
3857
|
.constant('ratingConfig', {
|
3287
3858
|
max: 5,
|
3288
3859
|
stateOn: null,
|
3289
|
-
stateOff: null
|
3860
|
+
stateOff: null,
|
3861
|
+
titles : ['one', 'two', 'three', 'four', 'five']
|
3290
3862
|
})
|
3291
3863
|
|
3292
3864
|
.controller('RatingController', ['$scope', '$attrs', 'ratingConfig', function($scope, $attrs, ratingConfig) {
|
@@ -3305,6 +3877,9 @@ angular.module('ui.bootstrap.rating', [])
|
|
3305
3877
|
|
3306
3878
|
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
|
3307
3879
|
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
|
3880
|
+
var tmpTitles = angular.isDefined($attrs.titles) ? $scope.$parent.$eval($attrs.titles) : ratingConfig.titles ;
|
3881
|
+
this.titles = angular.isArray(tmpTitles) && tmpTitles.length > 0 ?
|
3882
|
+
tmpTitles : ratingConfig.titles;
|
3308
3883
|
|
3309
3884
|
var ratingStates = angular.isDefined($attrs.ratingStates) ? $scope.$parent.$eval($attrs.ratingStates) :
|
3310
3885
|
new Array( angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max );
|
@@ -3313,14 +3888,22 @@ angular.module('ui.bootstrap.rating', [])
|
|
3313
3888
|
|
3314
3889
|
this.buildTemplateObjects = function(states) {
|
3315
3890
|
for (var i = 0, n = states.length; i < n; i++) {
|
3316
|
-
states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff }, states[i]);
|
3891
|
+
states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff, title: this.getTitle(i) }, states[i]);
|
3317
3892
|
}
|
3318
3893
|
return states;
|
3319
3894
|
};
|
3320
3895
|
|
3896
|
+
this.getTitle = function(index) {
|
3897
|
+
if (index >= this.titles.length) {
|
3898
|
+
return index + 1;
|
3899
|
+
} else {
|
3900
|
+
return this.titles[index];
|
3901
|
+
}
|
3902
|
+
};
|
3903
|
+
|
3321
3904
|
$scope.rate = function(value) {
|
3322
3905
|
if ( !$scope.readonly && value >= 0 && value <= $scope.range.length ) {
|
3323
|
-
ngModelCtrl.$setViewValue(value);
|
3906
|
+
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue === value ? 0 : value);
|
3324
3907
|
ngModelCtrl.$render();
|
3325
3908
|
}
|
3326
3909
|
};
|
@@ -3369,6 +3952,7 @@ angular.module('ui.bootstrap.rating', [])
|
|
3369
3952
|
};
|
3370
3953
|
});
|
3371
3954
|
|
3955
|
+
|
3372
3956
|
/**
|
3373
3957
|
* @ngdoc overview
|
3374
3958
|
* @name ui.bootstrap.tabs
|
@@ -3569,47 +4153,45 @@ angular.module('ui.bootstrap.tabs', [])
|
|
3569
4153
|
controller: function() {
|
3570
4154
|
//Empty controller so other directives can require being 'under' a tab
|
3571
4155
|
},
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3576
|
-
tabsetCtrl.select(scope);
|
3577
|
-
}
|
3578
|
-
});
|
3579
|
-
|
3580
|
-
scope.disabled = false;
|
3581
|
-
if ( attrs.disable ) {
|
3582
|
-
scope.$parent.$watch($parse(attrs.disable), function(value) {
|
3583
|
-
scope.disabled = !! value;
|
3584
|
-
});
|
3585
|
-
}
|
3586
|
-
|
3587
|
-
// Deprecation support of "disabled" parameter
|
3588
|
-
// fix(tab): IE9 disabled attr renders grey text on enabled tab #2677
|
3589
|
-
// This code is duplicated from the lines above to make it easy to remove once
|
3590
|
-
// the feature has been completely deprecated
|
3591
|
-
if ( attrs.disabled ) {
|
3592
|
-
$log.warn('Use of "disabled" attribute has been deprecated, please use "disable"');
|
3593
|
-
scope.$parent.$watch($parse(attrs.disabled), function(value) {
|
3594
|
-
scope.disabled = !! value;
|
3595
|
-
});
|
4156
|
+
link: function(scope, elm, attrs, tabsetCtrl, transclude) {
|
4157
|
+
scope.$watch('active', function(active) {
|
4158
|
+
if (active) {
|
4159
|
+
tabsetCtrl.select(scope);
|
3596
4160
|
}
|
4161
|
+
});
|
3597
4162
|
|
3598
|
-
|
3599
|
-
|
3600
|
-
|
3601
|
-
|
3602
|
-
};
|
4163
|
+
scope.disabled = false;
|
4164
|
+
if ( attrs.disable ) {
|
4165
|
+
scope.$parent.$watch($parse(attrs.disable), function(value) {
|
4166
|
+
scope.disabled = !! value;
|
4167
|
+
});
|
4168
|
+
}
|
3603
4169
|
|
3604
|
-
|
3605
|
-
|
3606
|
-
|
4170
|
+
// Deprecation support of "disabled" parameter
|
4171
|
+
// fix(tab): IE9 disabled attr renders grey text on enabled tab #2677
|
4172
|
+
// This code is duplicated from the lines above to make it easy to remove once
|
4173
|
+
// the feature has been completely deprecated
|
4174
|
+
if ( attrs.disabled ) {
|
4175
|
+
$log.warn('Use of "disabled" attribute has been deprecated, please use "disable"');
|
4176
|
+
scope.$parent.$watch($parse(attrs.disabled), function(value) {
|
4177
|
+
scope.disabled = !! value;
|
3607
4178
|
});
|
4179
|
+
}
|
3608
4180
|
|
3609
|
-
|
3610
|
-
|
3611
|
-
|
4181
|
+
scope.select = function() {
|
4182
|
+
if ( !scope.disabled ) {
|
4183
|
+
scope.active = true;
|
4184
|
+
}
|
3612
4185
|
};
|
4186
|
+
|
4187
|
+
tabsetCtrl.addTab(scope);
|
4188
|
+
scope.$on('$destroy', function() {
|
4189
|
+
tabsetCtrl.removeTab(scope);
|
4190
|
+
});
|
4191
|
+
|
4192
|
+
//We need to transclude later, once the content container is ready.
|
4193
|
+
//when this link happens, we're inside a tab heading.
|
4194
|
+
scope.$transcludeFn = transclude;
|
3613
4195
|
}
|
3614
4196
|
};
|
3615
4197
|
}])
|
@@ -3671,7 +4253,8 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3671
4253
|
meridians: null,
|
3672
4254
|
readonlyInput: false,
|
3673
4255
|
mousewheel: true,
|
3674
|
-
arrowkeys: true
|
4256
|
+
arrowkeys: true,
|
4257
|
+
showSpinners: true
|
3675
4258
|
})
|
3676
4259
|
|
3677
4260
|
.controller('TimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'timepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) {
|
@@ -3718,6 +4301,50 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3718
4301
|
});
|
3719
4302
|
}
|
3720
4303
|
|
4304
|
+
var min;
|
4305
|
+
$scope.$parent.$watch($parse($attrs.min), function(value) {
|
4306
|
+
var dt = new Date(value);
|
4307
|
+
min = isNaN(dt) ? undefined : dt;
|
4308
|
+
});
|
4309
|
+
|
4310
|
+
var max;
|
4311
|
+
$scope.$parent.$watch($parse($attrs.max), function(value) {
|
4312
|
+
var dt = new Date(value);
|
4313
|
+
max = isNaN(dt) ? undefined : dt;
|
4314
|
+
});
|
4315
|
+
|
4316
|
+
$scope.noIncrementHours = function() {
|
4317
|
+
var incrementedSelected = addMinutes(selected, hourStep * 60);
|
4318
|
+
return incrementedSelected > max ||
|
4319
|
+
(incrementedSelected < selected && incrementedSelected < min);
|
4320
|
+
};
|
4321
|
+
|
4322
|
+
$scope.noDecrementHours = function() {
|
4323
|
+
var decrementedSelected = addMinutes(selected, - hourStep * 60);
|
4324
|
+
return decrementedSelected < min ||
|
4325
|
+
(decrementedSelected > selected && decrementedSelected > max);
|
4326
|
+
};
|
4327
|
+
|
4328
|
+
$scope.noIncrementMinutes = function() {
|
4329
|
+
var incrementedSelected = addMinutes(selected, minuteStep);
|
4330
|
+
return incrementedSelected > max ||
|
4331
|
+
(incrementedSelected < selected && incrementedSelected < min);
|
4332
|
+
};
|
4333
|
+
|
4334
|
+
$scope.noDecrementMinutes = function() {
|
4335
|
+
var decrementedSelected = addMinutes(selected, - minuteStep);
|
4336
|
+
return decrementedSelected < min ||
|
4337
|
+
(decrementedSelected > selected && decrementedSelected > max);
|
4338
|
+
};
|
4339
|
+
|
4340
|
+
$scope.noToggleMeridian = function() {
|
4341
|
+
if (selected.getHours() < 13) {
|
4342
|
+
return addMinutes(selected, 12 * 60) > max;
|
4343
|
+
} else {
|
4344
|
+
return addMinutes(selected, - 12 * 60) < min;
|
4345
|
+
}
|
4346
|
+
};
|
4347
|
+
|
3721
4348
|
// 12H / 24H mode
|
3722
4349
|
$scope.showMeridian = timepickerConfig.showMeridian;
|
3723
4350
|
if ($attrs.showMeridian) {
|
@@ -3840,7 +4467,11 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3840
4467
|
|
3841
4468
|
if ( angular.isDefined(hours) ) {
|
3842
4469
|
selected.setHours( hours );
|
3843
|
-
|
4470
|
+
if (selected < min || selected > max) {
|
4471
|
+
invalidate(true);
|
4472
|
+
} else {
|
4473
|
+
refresh( 'h' );
|
4474
|
+
}
|
3844
4475
|
} else {
|
3845
4476
|
invalidate(true);
|
3846
4477
|
}
|
@@ -3859,7 +4490,11 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3859
4490
|
|
3860
4491
|
if ( angular.isDefined(minutes) ) {
|
3861
4492
|
selected.setMinutes( minutes );
|
3862
|
-
|
4493
|
+
if (selected < min || selected > max) {
|
4494
|
+
invalidate(undefined, true);
|
4495
|
+
} else {
|
4496
|
+
refresh( 'm' );
|
4497
|
+
}
|
3863
4498
|
} else {
|
3864
4499
|
invalidate(undefined, true);
|
3865
4500
|
}
|
@@ -3885,7 +4520,14 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3885
4520
|
if ( date ) {
|
3886
4521
|
selected = date;
|
3887
4522
|
}
|
3888
|
-
|
4523
|
+
|
4524
|
+
if (selected < min || selected > max) {
|
4525
|
+
ngModelCtrl.$setValidity('time', false);
|
4526
|
+
$scope.invalidHours = true;
|
4527
|
+
$scope.invalidMinutes = true;
|
4528
|
+
} else {
|
4529
|
+
makeValid();
|
4530
|
+
}
|
3889
4531
|
updateTemplate();
|
3890
4532
|
}
|
3891
4533
|
};
|
@@ -3917,26 +4559,45 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
3917
4559
|
$scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
3918
4560
|
}
|
3919
4561
|
|
3920
|
-
function addMinutes(
|
3921
|
-
var dt = new Date(
|
3922
|
-
|
4562
|
+
function addMinutes(date, minutes) {
|
4563
|
+
var dt = new Date(date.getTime() + minutes * 60000);
|
4564
|
+
var newDate = new Date(date);
|
4565
|
+
newDate.setHours(dt.getHours(), dt.getMinutes());
|
4566
|
+
return newDate;
|
4567
|
+
}
|
4568
|
+
|
4569
|
+
function addMinutesToSelected( minutes ) {
|
4570
|
+
selected = addMinutes( selected, minutes );
|
3923
4571
|
refresh();
|
3924
4572
|
}
|
3925
4573
|
|
4574
|
+
$scope.showSpinners = angular.isDefined($attrs.showSpinners) ?
|
4575
|
+
$scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;
|
4576
|
+
|
3926
4577
|
$scope.incrementHours = function() {
|
3927
|
-
|
4578
|
+
if (!$scope.noIncrementHours()) {
|
4579
|
+
addMinutesToSelected(hourStep * 60);
|
4580
|
+
}
|
3928
4581
|
};
|
3929
4582
|
$scope.decrementHours = function() {
|
3930
|
-
|
4583
|
+
if (!$scope.noDecrementHours()) {
|
4584
|
+
addMinutesToSelected(-hourStep * 60);
|
4585
|
+
}
|
3931
4586
|
};
|
3932
4587
|
$scope.incrementMinutes = function() {
|
3933
|
-
|
4588
|
+
if (!$scope.noIncrementMinutes()) {
|
4589
|
+
addMinutesToSelected(minuteStep);
|
4590
|
+
}
|
3934
4591
|
};
|
3935
4592
|
$scope.decrementMinutes = function() {
|
3936
|
-
|
4593
|
+
if (!$scope.noDecrementMinutes()) {
|
4594
|
+
addMinutesToSelected(-minuteStep);
|
4595
|
+
}
|
3937
4596
|
};
|
3938
4597
|
$scope.toggleMeridian = function() {
|
3939
|
-
|
4598
|
+
if (!$scope.noToggleMeridian()) {
|
4599
|
+
addMinutesToSelected(12 * 60 * (selected.getHours() < 12 ? 1 : -1));
|
4600
|
+
}
|
3940
4601
|
};
|
3941
4602
|
}])
|
3942
4603
|
|
@@ -4079,10 +4740,11 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4079
4740
|
};
|
4080
4741
|
}])
|
4081
4742
|
|
4082
|
-
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
|
4083
|
-
|
4743
|
+
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$window', '$rootScope', '$position', 'typeaheadParser',
|
4744
|
+
function ($compile, $parse, $q, $timeout, $document, $window, $rootScope, $position, typeaheadParser) {
|
4084
4745
|
|
4085
4746
|
var HOT_KEYS = [9, 13, 27, 38, 40];
|
4747
|
+
var eventDebounceTime = 200;
|
4086
4748
|
|
4087
4749
|
return {
|
4088
4750
|
require:'ngModel',
|
@@ -4091,7 +4753,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4091
4753
|
//SUPPORTED ATTRIBUTES (OPTIONS)
|
4092
4754
|
|
4093
4755
|
//minimal no of characters that needs to be entered before typeahead kicks-in
|
4094
|
-
var
|
4756
|
+
var minLength = originalScope.$eval(attrs.typeaheadMinLength);
|
4757
|
+
if (!minLength && minLength !== 0) {
|
4758
|
+
minLength = 1;
|
4759
|
+
}
|
4095
4760
|
|
4096
4761
|
//minimal wait time after last character typed before typeahead kicks-in
|
4097
4762
|
var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
|
@@ -4105,12 +4770,21 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4105
4770
|
//a callback executed when a match is selected
|
4106
4771
|
var onSelectCallback = $parse(attrs.typeaheadOnSelect);
|
4107
4772
|
|
4773
|
+
//should it select highlighted popup value when losing focus?
|
4774
|
+
var isSelectOnBlur = angular.isDefined(attrs.typeaheadSelectOnBlur) ? originalScope.$eval(attrs.typeaheadSelectOnBlur) : false;
|
4775
|
+
|
4776
|
+
//binding to a variable that indicates if there were no results after the query is completed
|
4777
|
+
var isNoResultsSetter = $parse(attrs.typeaheadNoResults).assign || angular.noop;
|
4778
|
+
|
4108
4779
|
var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
|
4109
4780
|
|
4110
4781
|
var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false;
|
4111
4782
|
|
4112
4783
|
var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false;
|
4113
4784
|
|
4785
|
+
//If input matches an item of the list exactly, select it automatically
|
4786
|
+
var selectOnExact = attrs.typeaheadSelectOnExact ? originalScope.$eval(attrs.typeaheadSelectOnExact) : false;
|
4787
|
+
|
4114
4788
|
//INTERNAL VARIABLES
|
4115
4789
|
|
4116
4790
|
//model setter executed upon match selection
|
@@ -4121,6 +4795,11 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4121
4795
|
|
4122
4796
|
var hasFocus;
|
4123
4797
|
|
4798
|
+
//Used to avoid bug in iOS webview where iOS keyboard does not fire
|
4799
|
+
//mousedown & mouseup events
|
4800
|
+
//Issue #3699
|
4801
|
+
var selected;
|
4802
|
+
|
4124
4803
|
//create a child scope for the typeahead directive so we are not polluting original scope
|
4125
4804
|
//with typeahead-specific data (matches, query etc.)
|
4126
4805
|
var scope = originalScope.$new();
|
@@ -4143,6 +4822,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4143
4822
|
matches: 'matches',
|
4144
4823
|
active: 'activeIdx',
|
4145
4824
|
select: 'select(activeIdx)',
|
4825
|
+
'move-in-progress': 'moveInProgress',
|
4146
4826
|
query: 'query',
|
4147
4827
|
position: 'position'
|
4148
4828
|
});
|
@@ -4171,10 +4851,20 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4171
4851
|
}
|
4172
4852
|
});
|
4173
4853
|
|
4854
|
+
var inputIsExactMatch = function(inputValue, index) {
|
4855
|
+
|
4856
|
+
if (scope.matches.length > index && inputValue) {
|
4857
|
+
return inputValue.toUpperCase() === scope.matches[index].label.toUpperCase();
|
4858
|
+
}
|
4859
|
+
|
4860
|
+
return false;
|
4861
|
+
};
|
4862
|
+
|
4174
4863
|
var getMatchesAsync = function(inputValue) {
|
4175
4864
|
|
4176
4865
|
var locals = {$viewValue: inputValue};
|
4177
4866
|
isLoadingSetter(originalScope, true);
|
4867
|
+
isNoResultsSetter(originalScope, false);
|
4178
4868
|
$q.when(parserResult.source(originalScope, locals)).then(function(matches) {
|
4179
4869
|
|
4180
4870
|
//it might happen that several async queries were in progress if a user were typing fast
|
@@ -4184,6 +4874,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4184
4874
|
if (matches && matches.length > 0) {
|
4185
4875
|
|
4186
4876
|
scope.activeIdx = focusFirst ? 0 : -1;
|
4877
|
+
isNoResultsSetter(originalScope, false);
|
4187
4878
|
scope.matches.length = 0;
|
4188
4879
|
|
4189
4880
|
//transform labels
|
@@ -4200,12 +4891,17 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4200
4891
|
//position pop-up with matches - we need to re-calculate its position each time we are opening a window
|
4201
4892
|
//with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
|
4202
4893
|
//due to other elements being rendered
|
4203
|
-
|
4204
|
-
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
4894
|
+
recalculatePosition();
|
4205
4895
|
|
4206
4896
|
element.attr('aria-expanded', true);
|
4897
|
+
|
4898
|
+
//Select the single remaining option if user input matches
|
4899
|
+
if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) {
|
4900
|
+
scope.select(0);
|
4901
|
+
}
|
4207
4902
|
} else {
|
4208
4903
|
resetMatches();
|
4904
|
+
isNoResultsSetter(originalScope, true);
|
4209
4905
|
}
|
4210
4906
|
}
|
4211
4907
|
if (onCurrentRequest) {
|
@@ -4214,9 +4910,52 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4214
4910
|
}, function(){
|
4215
4911
|
resetMatches();
|
4216
4912
|
isLoadingSetter(originalScope, false);
|
4913
|
+
isNoResultsSetter(originalScope, true);
|
4217
4914
|
});
|
4218
4915
|
};
|
4219
4916
|
|
4917
|
+
// bind events only if appendToBody params exist - performance feature
|
4918
|
+
if (appendToBody) {
|
4919
|
+
angular.element($window).bind('resize', fireRecalculating);
|
4920
|
+
$document.find('body').bind('scroll', fireRecalculating);
|
4921
|
+
}
|
4922
|
+
|
4923
|
+
// Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
|
4924
|
+
var timeoutEventPromise;
|
4925
|
+
|
4926
|
+
// Default progress type
|
4927
|
+
scope.moveInProgress = false;
|
4928
|
+
|
4929
|
+
function fireRecalculating() {
|
4930
|
+
if(!scope.moveInProgress){
|
4931
|
+
scope.moveInProgress = true;
|
4932
|
+
scope.$digest();
|
4933
|
+
}
|
4934
|
+
|
4935
|
+
// Cancel previous timeout
|
4936
|
+
if (timeoutEventPromise) {
|
4937
|
+
$timeout.cancel(timeoutEventPromise);
|
4938
|
+
}
|
4939
|
+
|
4940
|
+
// Debounced executing recalculate after events fired
|
4941
|
+
timeoutEventPromise = $timeout(function () {
|
4942
|
+
// if popup is visible
|
4943
|
+
if (scope.matches.length) {
|
4944
|
+
recalculatePosition();
|
4945
|
+
}
|
4946
|
+
|
4947
|
+
scope.moveInProgress = false;
|
4948
|
+
scope.$digest();
|
4949
|
+
}, eventDebounceTime);
|
4950
|
+
}
|
4951
|
+
|
4952
|
+
// recalculate actual position and set new values to scope
|
4953
|
+
// after digest loop is popup in right position
|
4954
|
+
function recalculatePosition() {
|
4955
|
+
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
4956
|
+
scope.position.top += element.prop('offsetHeight');
|
4957
|
+
}
|
4958
|
+
|
4220
4959
|
resetMatches();
|
4221
4960
|
|
4222
4961
|
//we need to propagate user's query so we can higlight matches
|
@@ -4243,7 +4982,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4243
4982
|
|
4244
4983
|
hasFocus = true;
|
4245
4984
|
|
4246
|
-
if (inputValue && inputValue.length >=
|
4985
|
+
if (minLength === 0 || inputValue && inputValue.length >= minLength) {
|
4247
4986
|
if (waitTime > 0) {
|
4248
4987
|
cancelPreviousTimeout();
|
4249
4988
|
scheduleSearchWithTimeout(inputValue);
|
@@ -4262,7 +5001,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4262
5001
|
if (!inputValue) {
|
4263
5002
|
// Reset in case user had typed something previously.
|
4264
5003
|
modelCtrl.$setValidity('editable', true);
|
4265
|
-
return
|
5004
|
+
return null;
|
4266
5005
|
} else {
|
4267
5006
|
modelCtrl.$setValidity('editable', false);
|
4268
5007
|
return undefined;
|
@@ -4305,6 +5044,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4305
5044
|
var locals = {};
|
4306
5045
|
var model, item;
|
4307
5046
|
|
5047
|
+
selected = true;
|
4308
5048
|
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
|
4309
5049
|
model = parserResult.modelMapper(originalScope, locals);
|
4310
5050
|
$setModelValue(originalScope, model);
|
@@ -4332,8 +5072,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4332
5072
|
return;
|
4333
5073
|
}
|
4334
5074
|
|
4335
|
-
// if there's nothing selected (i.e. focusFirst) and enter is hit,
|
4336
|
-
if (scope.activeIdx
|
5075
|
+
// if there's nothing selected (i.e. focusFirst) and enter or tab is hit, clear the results
|
5076
|
+
if (scope.activeIdx === -1 && (evt.which === 9 || evt.which === 13)) {
|
5077
|
+
resetMatches();
|
5078
|
+
scope.$digest();
|
4337
5079
|
return;
|
4338
5080
|
}
|
4339
5081
|
|
@@ -4360,15 +5102,26 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4360
5102
|
}
|
4361
5103
|
});
|
4362
5104
|
|
4363
|
-
element.bind('blur', function (
|
5105
|
+
element.bind('blur', function () {
|
5106
|
+
if (isSelectOnBlur && scope.matches.length && scope.activeIdx !== -1 && !selected) {
|
5107
|
+
selected = true;
|
5108
|
+
scope.$apply(function () {
|
5109
|
+
scope.select(scope.activeIdx);
|
5110
|
+
});
|
5111
|
+
}
|
4364
5112
|
hasFocus = false;
|
5113
|
+
selected = false;
|
4365
5114
|
});
|
4366
5115
|
|
4367
5116
|
// Keep reference to click handler to unbind it.
|
4368
5117
|
var dismissClickHandler = function (evt) {
|
4369
|
-
|
5118
|
+
// Issue #3973
|
5119
|
+
// Firefox treats right click as a click on document
|
5120
|
+
if (element[0] !== evt.target && evt.which !== 3 && scope.matches.length !== 0) {
|
4370
5121
|
resetMatches();
|
4371
|
-
|
5122
|
+
if (!$rootScope.$$phase) {
|
5123
|
+
scope.$digest();
|
5124
|
+
}
|
4372
5125
|
}
|
4373
5126
|
};
|
4374
5127
|
|
@@ -4402,7 +5155,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4402
5155
|
matches:'=',
|
4403
5156
|
query:'=',
|
4404
5157
|
active:'=',
|
4405
|
-
position:'
|
5158
|
+
position:'&',
|
5159
|
+
moveInProgress:'=',
|
4406
5160
|
select:'&'
|
4407
5161
|
},
|
4408
5162
|
replace:true,
|
@@ -4462,10 +5216,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
|
|
4462
5216
|
|
4463
5217
|
angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
|
4464
5218
|
$templateCache.put("template/accordion/accordion-group.html",
|
4465
|
-
"<div class=\"panel panel-default\">\n" +
|
5219
|
+
"<div class=\"panel panel-default\" ng-class=\"{'panel-open': isOpen}\">\n" +
|
4466
5220
|
" <div class=\"panel-heading\">\n" +
|
4467
5221
|
" <h4 class=\"panel-title\">\n" +
|
4468
|
-
" <a href
|
5222
|
+
" <a href tabindex=\"0\" class=\"accordion-toggle\" ng-click=\"toggleOpen()\" accordion-transclude=\"heading\"><span ng-class=\"{'text-muted': isDisabled}\">{{heading}}</span></a>\n" +
|
4469
5223
|
" </h4>\n" +
|
4470
5224
|
" </div>\n" +
|
4471
5225
|
" <div class=\"panel-collapse collapse\" collapse=\"!isOpen\">\n" +
|
@@ -4482,8 +5236,8 @@ angular.module("template/accordion/accordion.html", []).run(["$templateCache", f
|
|
4482
5236
|
|
4483
5237
|
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
|
4484
5238
|
$templateCache.put("template/alert/alert.html",
|
4485
|
-
"<div class=\"alert\" ng-class=\"['alert-' + (type || 'warning'), closeable ? 'alert-
|
4486
|
-
" <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close()\">\n" +
|
5239
|
+
"<div class=\"alert\" ng-class=\"['alert-' + (type || 'warning'), closeable ? 'alert-dismissible' : null]\" role=\"alert\">\n" +
|
5240
|
+
" <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close($event)\">\n" +
|
4487
5241
|
" <span aria-hidden=\"true\">×</span>\n" +
|
4488
5242
|
" <span class=\"sr-only\">Close</span>\n" +
|
4489
5243
|
" </button>\n" +
|
@@ -4496,7 +5250,7 @@ angular.module("template/carousel/carousel.html", []).run(["$templateCache", fun
|
|
4496
5250
|
$templateCache.put("template/carousel/carousel.html",
|
4497
5251
|
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
|
4498
5252
|
" <ol class=\"carousel-indicators\" ng-show=\"slides.length > 1\">\n" +
|
4499
|
-
" <li ng-repeat=\"slide in slides | orderBy:
|
5253
|
+
" <li ng-repeat=\"slide in slides | orderBy:indexOfSlide track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\"></li>\n" +
|
4500
5254
|
" </ol>\n" +
|
4501
5255
|
" <div class=\"carousel-inner\" ng-transclude></div>\n" +
|
4502
5256
|
" <a class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides.length > 1\"><span class=\"glyphicon glyphicon-chevron-left\"></span></a>\n" +
|
@@ -4524,23 +5278,23 @@ angular.module("template/datepicker/datepicker.html", []).run(["$templateCache",
|
|
4524
5278
|
|
4525
5279
|
angular.module("template/datepicker/day.html", []).run(["$templateCache", function($templateCache) {
|
4526
5280
|
$templateCache.put("template/datepicker/day.html",
|
4527
|
-
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
5281
|
+
"<table role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
4528
5282
|
" <thead>\n" +
|
4529
5283
|
" <tr>\n" +
|
4530
5284
|
" <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" +
|
4531
|
-
" <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()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
5285
|
+
" <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()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
4532
5286
|
" <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" +
|
4533
5287
|
" </tr>\n" +
|
4534
5288
|
" <tr>\n" +
|
4535
|
-
" <th ng-
|
4536
|
-
" <th ng-repeat=\"label in labels track by $index\" class=\"text-center\"><small aria-label=\"{{label.full}}\">{{label.abbr}}</small></th>\n" +
|
5289
|
+
" <th ng-if=\"showWeeks\" class=\"text-center\"></th>\n" +
|
5290
|
+
" <th ng-repeat=\"label in ::labels track by $index\" class=\"text-center\"><small aria-label=\"{{::label.full}}\">{{::label.abbr}}</small></th>\n" +
|
4537
5291
|
" </tr>\n" +
|
4538
5292
|
" </thead>\n" +
|
4539
5293
|
" <tbody>\n" +
|
4540
5294
|
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
4541
|
-
" <td ng-
|
4542
|
-
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\"
|
4543
|
-
" <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" +
|
5295
|
+
" <td ng-if=\"showWeeks\" class=\"text-center h6\"><em>{{ weekNumbers[$index] }}</em></td>\n" +
|
5296
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{::dt.uid}}\" ng-class=\"::dt.customClass\">\n" +
|
5297
|
+
" <button type=\"button\" style=\"min-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" +
|
4544
5298
|
" </td>\n" +
|
4545
5299
|
" </tr>\n" +
|
4546
5300
|
" </tbody>\n" +
|
@@ -4550,18 +5304,18 @@ angular.module("template/datepicker/day.html", []).run(["$templateCache", functi
|
|
4550
5304
|
|
4551
5305
|
angular.module("template/datepicker/month.html", []).run(["$templateCache", function($templateCache) {
|
4552
5306
|
$templateCache.put("template/datepicker/month.html",
|
4553
|
-
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
5307
|
+
"<table role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
4554
5308
|
" <thead>\n" +
|
4555
5309
|
" <tr>\n" +
|
4556
5310
|
" <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" +
|
4557
|
-
" <th><button id=\"{{uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"toggleMode()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
5311
|
+
" <th><button id=\"{{::uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"toggleMode()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
4558
5312
|
" <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" +
|
4559
5313
|
" </tr>\n" +
|
4560
5314
|
" </thead>\n" +
|
4561
5315
|
" <tbody>\n" +
|
4562
5316
|
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
4563
|
-
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\"
|
4564
|
-
" <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" +
|
5317
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{::dt.uid}}\" ng-class=\"::dt.customClass\">\n" +
|
5318
|
+
" <button type=\"button\" style=\"min-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" +
|
4565
5319
|
" </td>\n" +
|
4566
5320
|
" </tr>\n" +
|
4567
5321
|
" </tbody>\n" +
|
@@ -4571,7 +5325,7 @@ angular.module("template/datepicker/month.html", []).run(["$templateCache", func
|
|
4571
5325
|
|
4572
5326
|
angular.module("template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
|
4573
5327
|
$templateCache.put("template/datepicker/popup.html",
|
4574
|
-
"<ul class=\"dropdown-menu\" ng-style=\"
|
5328
|
+
"<ul class=\"dropdown-menu\" ng-if=\"isOpen\" style=\"display: block\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" ng-keydown=\"keydown($event)\" ng-click=\"$event.stopPropagation()\">\n" +
|
4575
5329
|
" <li ng-transclude></li>\n" +
|
4576
5330
|
" <li ng-if=\"showButtonBar\" style=\"padding:10px 9px 2px\">\n" +
|
4577
5331
|
" <span class=\"btn-group pull-left\">\n" +
|
@@ -4586,18 +5340,18 @@ angular.module("template/datepicker/popup.html", []).run(["$templateCache", func
|
|
4586
5340
|
|
4587
5341
|
angular.module("template/datepicker/year.html", []).run(["$templateCache", function($templateCache) {
|
4588
5342
|
$templateCache.put("template/datepicker/year.html",
|
4589
|
-
"<table role=\"grid\" aria-labelledby=\"{{uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
5343
|
+
"<table role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
|
4590
5344
|
" <thead>\n" +
|
4591
5345
|
" <tr>\n" +
|
4592
5346
|
" <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" +
|
4593
|
-
" <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()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
5347
|
+
" <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()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\" style=\"width:100%;\"><strong>{{title}}</strong></button></th>\n" +
|
4594
5348
|
" <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" +
|
4595
5349
|
" </tr>\n" +
|
4596
5350
|
" </thead>\n" +
|
4597
5351
|
" <tbody>\n" +
|
4598
5352
|
" <tr ng-repeat=\"row in rows track by $index\">\n" +
|
4599
|
-
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{dt.uid}}\"
|
4600
|
-
" <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" +
|
5353
|
+
" <td ng-repeat=\"dt in row track by dt.date\" class=\"text-center\" role=\"gridcell\" id=\"{{::dt.uid}}\">\n" +
|
5354
|
+
" <button type=\"button\" style=\"min-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" +
|
4601
5355
|
" </td>\n" +
|
4602
5356
|
" </tr>\n" +
|
4603
5357
|
" </tbody>\n" +
|
@@ -4609,7 +5363,7 @@ angular.module("template/modal/backdrop.html", []).run(["$templateCache", functi
|
|
4609
5363
|
$templateCache.put("template/modal/backdrop.html",
|
4610
5364
|
"<div class=\"modal-backdrop\"\n" +
|
4611
5365
|
" modal-animation-class=\"fade\"\n" +
|
4612
|
-
"
|
5366
|
+
" modal-in-class=\"in\"\n" +
|
4613
5367
|
" ng-style=\"{'z-index': 1040 + (index && 1 || 0) + index*10}\"\n" +
|
4614
5368
|
"></div>\n" +
|
4615
5369
|
"");
|
@@ -4619,7 +5373,8 @@ angular.module("template/modal/window.html", []).run(["$templateCache", function
|
|
4619
5373
|
$templateCache.put("template/modal/window.html",
|
4620
5374
|
"<div modal-render=\"{{$isRendered}}\" tabindex=\"-1\" role=\"dialog\" class=\"modal\"\n" +
|
4621
5375
|
" modal-animation-class=\"fade\"\n" +
|
4622
|
-
"
|
5376
|
+
" modal-in-class=\"in\"\n" +
|
5377
|
+
" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
|
4623
5378
|
" <div class=\"modal-dialog\" ng-class=\"size ? 'modal-' + size : ''\"><div class=\"modal-content\" modal-transclude></div></div>\n" +
|
4624
5379
|
"</div>\n" +
|
4625
5380
|
"");
|
@@ -4628,20 +5383,21 @@ angular.module("template/modal/window.html", []).run(["$templateCache", function
|
|
4628
5383
|
angular.module("template/pagination/pager.html", []).run(["$templateCache", function($templateCache) {
|
4629
5384
|
$templateCache.put("template/pagination/pager.html",
|
4630
5385
|
"<ul class=\"pager\">\n" +
|
4631
|
-
" <li ng-class=\"{disabled: noPrevious(), previous: align}\"><a href ng-click=\"selectPage(page - 1, $event)\">{{getText('previous')}}</a></li>\n" +
|
4632
|
-
" <li ng-class=\"{disabled: noNext(), next: align}\"><a href ng-click=\"selectPage(page + 1, $event)\">{{getText('next')}}</a></li>\n" +
|
5386
|
+
" <li ng-class=\"{disabled: noPrevious(), previous: align}\"><a href ng-click=\"selectPage(page - 1, $event)\">{{::getText('previous')}}</a></li>\n" +
|
5387
|
+
" <li ng-class=\"{disabled: noNext(), next: align}\"><a href ng-click=\"selectPage(page + 1, $event)\">{{::getText('next')}}</a></li>\n" +
|
4633
5388
|
"</ul>");
|
4634
5389
|
}]);
|
4635
5390
|
|
4636
5391
|
angular.module("template/pagination/pagination.html", []).run(["$templateCache", function($templateCache) {
|
4637
5392
|
$templateCache.put("template/pagination/pagination.html",
|
4638
5393
|
"<ul class=\"pagination\">\n" +
|
4639
|
-
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noPrevious()}\"><a href ng-click=\"selectPage(1, $event)\">{{getText('first')}}</a></li>\n" +
|
4640
|
-
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noPrevious()}\"><a href ng-click=\"selectPage(page - 1, $event)\">{{getText('previous')}}</a></li>\n" +
|
4641
|
-
" <li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active}\"><a href ng-click=\"selectPage(page.number, $event)\">{{page.text}}</a></li>\n" +
|
4642
|
-
" <li ng-if=\"directionLinks\" ng-class=\"{disabled: noNext()}\"><a href ng-click=\"selectPage(page + 1, $event)\">{{getText('next')}}</a></li>\n" +
|
4643
|
-
" <li ng-if=\"boundaryLinks\" ng-class=\"{disabled: noNext()}\"><a href ng-click=\"selectPage(totalPages, $event)\">{{getText('last')}}</a></li>\n" +
|
4644
|
-
"</ul
|
5394
|
+
" <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-first\"><a href ng-click=\"selectPage(1, $event)\">{{::getText('first')}}</a></li>\n" +
|
5395
|
+
" <li ng-if=\"::directionLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-prev\"><a href ng-click=\"selectPage(page - 1, $event)\">{{::getText('previous')}}</a></li>\n" +
|
5396
|
+
" <li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active,disabled: ngDisabled&&!page.active}\" class=\"pagination-page\"><a href ng-click=\"selectPage(page.number, $event)\">{{page.text}}</a></li>\n" +
|
5397
|
+
" <li ng-if=\"::directionLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-next\"><a href ng-click=\"selectPage(page + 1, $event)\">{{::getText('next')}}</a></li>\n" +
|
5398
|
+
" <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-last\"><a href ng-click=\"selectPage(totalPages, $event)\">{{::getText('last')}}</a></li>\n" +
|
5399
|
+
"</ul>\n" +
|
5400
|
+
"");
|
4645
5401
|
}]);
|
4646
5402
|
|
4647
5403
|
angular.module("template/tooltip/tooltip-html-popup.html", []).run(["$templateCache", function($templateCache) {
|
@@ -4694,8 +5450,8 @@ angular.module("template/tooltip/tooltip-template-popup.html", []).run(["$templa
|
|
4694
5450
|
"");
|
4695
5451
|
}]);
|
4696
5452
|
|
4697
|
-
angular.module("template/popover/popover-
|
4698
|
-
$templateCache.put("template/popover/popover-
|
5453
|
+
angular.module("template/popover/popover-html.html", []).run(["$templateCache", function($templateCache) {
|
5454
|
+
$templateCache.put("template/popover/popover-html.html",
|
4699
5455
|
"<div class=\"popover\"\n" +
|
4700
5456
|
" tooltip-animation-class=\"fade\"\n" +
|
4701
5457
|
" tooltip-classes\n" +
|
@@ -4704,22 +5460,25 @@ angular.module("template/popover/popover-template.html", []).run(["$templateCach
|
|
4704
5460
|
"\n" +
|
4705
5461
|
" <div class=\"popover-inner\">\n" +
|
4706
5462
|
" <h3 class=\"popover-title\" ng-bind=\"title\" ng-if=\"title\"></h3>\n" +
|
4707
|
-
" <div class=\"popover-content\"\n" +
|
4708
|
-
" tooltip-template-transclude=\"contentExp()\"\n" +
|
4709
|
-
" tooltip-template-transclude-scope=\"originScope()\"></div>\n" +
|
5463
|
+
" <div class=\"popover-content\" ng-bind-html=\"contentExp()\"></div>\n" +
|
4710
5464
|
" </div>\n" +
|
4711
5465
|
"</div>\n" +
|
4712
5466
|
"");
|
4713
5467
|
}]);
|
4714
5468
|
|
4715
|
-
angular.module("template/popover/popover-
|
4716
|
-
$templateCache.put("template/popover/popover-
|
4717
|
-
"<div class=\"popover
|
5469
|
+
angular.module("template/popover/popover-template.html", []).run(["$templateCache", function($templateCache) {
|
5470
|
+
$templateCache.put("template/popover/popover-template.html",
|
5471
|
+
"<div class=\"popover\"\n" +
|
5472
|
+
" tooltip-animation-class=\"fade\"\n" +
|
5473
|
+
" tooltip-classes\n" +
|
5474
|
+
" ng-class=\"{ in: isOpen() }\">\n" +
|
4718
5475
|
" <div class=\"arrow\"></div>\n" +
|
4719
5476
|
"\n" +
|
4720
5477
|
" <div class=\"popover-inner\">\n" +
|
4721
|
-
" <h3 class=\"popover-title\" ng-bind=\"title\" ng-
|
4722
|
-
" <div class=\"popover-content\"
|
5478
|
+
" <h3 class=\"popover-title\" ng-bind=\"title\" ng-if=\"title\"></h3>\n" +
|
5479
|
+
" <div class=\"popover-content\"\n" +
|
5480
|
+
" tooltip-template-transclude=\"contentExp()\"\n" +
|
5481
|
+
" tooltip-template-transclude-scope=\"originScope()\"></div>\n" +
|
4723
5482
|
" </div>\n" +
|
4724
5483
|
"</div>\n" +
|
4725
5484
|
"");
|
@@ -4743,7 +5502,7 @@ angular.module("template/popover/popover.html", []).run(["$templateCache", funct
|
|
4743
5502
|
|
4744
5503
|
angular.module("template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
|
4745
5504
|
$templateCache.put("template/progressbar/bar.html",
|
4746
|
-
"<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 < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" ng-transclude></div>\n" +
|
5505
|
+
"<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 < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" style=\"min-width: 0;\" ng-transclude></div>\n" +
|
4747
5506
|
"");
|
4748
5507
|
}]);
|
4749
5508
|
|
@@ -4755,7 +5514,7 @@ angular.module("template/progressbar/progress.html", []).run(["$templateCache",
|
|
4755
5514
|
angular.module("template/progressbar/progressbar.html", []).run(["$templateCache", function($templateCache) {
|
4756
5515
|
$templateCache.put("template/progressbar/progressbar.html",
|
4757
5516
|
"<div class=\"progress\">\n" +
|
4758
|
-
" <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 < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" ng-transclude></div>\n" +
|
5517
|
+
" <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 < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" style=\"min-width: 0;\" ng-transclude></div>\n" +
|
4759
5518
|
"</div>\n" +
|
4760
5519
|
"");
|
4761
5520
|
}]);
|
@@ -4763,10 +5522,10 @@ angular.module("template/progressbar/progressbar.html", []).run(["$templateCache
|
|
4763
5522
|
angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
|
4764
5523
|
$templateCache.put("template/rating/rating.html",
|
4765
5524
|
"<span ng-mouseleave=\"reset()\" ng-keydown=\"onKeydown($event)\" tabindex=\"0\" role=\"slider\" aria-valuemin=\"0\" aria-valuemax=\"{{range.length}}\" aria-valuenow=\"{{value}}\">\n" +
|
4766
|
-
" <
|
4767
|
-
"
|
4768
|
-
"
|
4769
|
-
"
|
5525
|
+
" <span ng-repeat-start=\"r in range track by $index\" class=\"sr-only\">({{ $index < value ? '*' : ' ' }})</span>\n" +
|
5526
|
+
" <i ng-repeat-end 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')\" ng-attr-title=\"{{r.title}}\" ></i>\n" +
|
5527
|
+
"</span>\n" +
|
5528
|
+
"");
|
4770
5529
|
}]);
|
4771
5530
|
|
4772
5531
|
angular.module("template/tabs/tab.html", []).run(["$templateCache", function($templateCache) {
|
@@ -4795,46 +5554,47 @@ angular.module("template/tabs/tabset.html", []).run(["$templateCache", function(
|
|
4795
5554
|
angular.module("template/timepicker/timepicker.html", []).run(["$templateCache", function($templateCache) {
|
4796
5555
|
$templateCache.put("template/timepicker/timepicker.html",
|
4797
5556
|
"<table>\n" +
|
4798
|
-
"
|
4799
|
-
"
|
4800
|
-
"
|
4801
|
-
"
|
4802
|
-
"
|
4803
|
-
"
|
4804
|
-
"
|
4805
|
-
"
|
4806
|
-
"
|
4807
|
-
"
|
4808
|
-
"
|
4809
|
-
"
|
4810
|
-
"
|
4811
|
-
"
|
4812
|
-
"
|
4813
|
-
"
|
4814
|
-
"
|
4815
|
-
"
|
4816
|
-
"
|
4817
|
-
"
|
4818
|
-
"
|
4819
|
-
"
|
4820
|
-
"
|
4821
|
-
"
|
5557
|
+
" <tbody>\n" +
|
5558
|
+
" <tr class=\"text-center\" ng-show=\"::showSpinners\">\n" +
|
5559
|
+
" <td><a ng-click=\"incrementHours()\" ng-class=\"{disabled: noIncrementHours()}\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
|
5560
|
+
" <td> </td>\n" +
|
5561
|
+
" <td><a ng-click=\"incrementMinutes()\" ng-class=\"{disabled: noIncrementMinutes()}\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
|
5562
|
+
" <td ng-show=\"showMeridian\"></td>\n" +
|
5563
|
+
" </tr>\n" +
|
5564
|
+
" <tr>\n" +
|
5565
|
+
" <td class=\"form-group\" ng-class=\"{'has-error': invalidHours}\">\n" +
|
5566
|
+
" <input style=\"width:50px;\" type=\"text\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"form-control text-center\" ng-readonly=\"::readonlyInput\" maxlength=\"2\">\n" +
|
5567
|
+
" </td>\n" +
|
5568
|
+
" <td>:</td>\n" +
|
5569
|
+
" <td class=\"form-group\" ng-class=\"{'has-error': invalidMinutes}\">\n" +
|
5570
|
+
" <input style=\"width:50px;\" type=\"text\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"form-control text-center\" ng-readonly=\"::readonlyInput\" maxlength=\"2\">\n" +
|
5571
|
+
" </td>\n" +
|
5572
|
+
" <td ng-show=\"showMeridian\"><button type=\"button\" ng-class=\"{disabled: noToggleMeridian()}\" class=\"btn btn-default text-center\" ng-click=\"toggleMeridian()\">{{meridian}}</button></td>\n" +
|
5573
|
+
" </tr>\n" +
|
5574
|
+
" <tr class=\"text-center\" ng-show=\"::showSpinners\">\n" +
|
5575
|
+
" <td><a ng-click=\"decrementHours()\" ng-class=\"{disabled: noDecrementHours()}\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
|
5576
|
+
" <td> </td>\n" +
|
5577
|
+
" <td><a ng-click=\"decrementMinutes()\" ng-class=\"{disabled: noDecrementMinutes()}\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
|
5578
|
+
" <td ng-show=\"showMeridian\"></td>\n" +
|
5579
|
+
" </tr>\n" +
|
5580
|
+
" </tbody>\n" +
|
4822
5581
|
"</table>\n" +
|
4823
5582
|
"");
|
4824
5583
|
}]);
|
4825
5584
|
|
4826
5585
|
angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
|
4827
5586
|
$templateCache.put("template/typeahead/typeahead-match.html",
|
4828
|
-
"<a tabindex=\"-1\" bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a
|
5587
|
+
"<a href tabindex=\"-1\" bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a>\n" +
|
5588
|
+
"");
|
4829
5589
|
}]);
|
4830
5590
|
|
4831
5591
|
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
|
4832
5592
|
$templateCache.put("template/typeahead/typeahead-popup.html",
|
4833
|
-
"<ul class=\"dropdown-menu\" ng-show=\"isOpen()\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
|
4834
|
-
" <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" +
|
5593
|
+
"<ul class=\"dropdown-menu\" ng-show=\"isOpen() && !moveInProgress\" ng-style=\"{top: position().top+'px', left: position().left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
|
5594
|
+
" <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" +
|
4835
5595
|
" <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
|
4836
5596
|
" </li>\n" +
|
4837
5597
|
"</ul>\n" +
|
4838
5598
|
"");
|
4839
5599
|
}]);
|
4840
|
-
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');
|
5600
|
+
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');
|