|
304 | 304 | */
|
305 | 305 | this.calendarPaneOpenedFrom = null;
|
306 | 306 |
|
| 307 | + /** @type {String} Unique id for the calendar pane. */ |
307 | 308 | this.calendarPane.id = 'md-date-pane' + $mdUtil.nextUid();
|
308 | 309 |
|
309 |
| - $mdTheming($element); |
310 |
| - $mdTheming(angular.element(this.calendarPane)); |
311 |
| - |
312 | 310 | /** Pre-bound click handler is saved so that the event listener can be removed. */
|
313 | 311 | this.bodyClickHandler = angular.bind(this, this.handleBodyClick);
|
314 | 312 |
|
315 | 313 | /** Pre-bound resize handler so that the event listener can be removed. */
|
316 | 314 | this.windowResizeHandler = $mdUtil.debounce(angular.bind(this, this.closeCalendarPane), 100);
|
317 | 315 |
|
| 316 | + /** Pre-bound handler for the window blur event. Allows for it to be removed later. */ |
| 317 | + this.windowBlurHandler = angular.bind(this, this.handleWindowBlur); |
| 318 | + |
318 | 319 | // Unless the user specifies so, the datepicker should not be a tab stop.
|
319 | 320 | // This is necessary because ngAria might add a tabindex to anything with an ng-model
|
320 | 321 | // (based on whether or not the user has turned that particular feature on/off).
|
321 | 322 | if (!$attrs.tabindex) {
|
322 | 323 | $element.attr('tabindex', '-1');
|
323 | 324 | }
|
324 | 325 |
|
| 326 | + $mdTheming($element); |
| 327 | + $mdTheming(angular.element(this.calendarPane)); |
| 328 | + |
325 | 329 | this.installPropertyInterceptors();
|
326 | 330 | this.attachChangeListeners();
|
327 | 331 | this.attachInteractionListeners();
|
|
415 | 419 |
|
416 | 420 | if (self.openOnFocus) {
|
417 | 421 | self.ngInputElement.on('focus', angular.bind(self, self.openCalendarPane));
|
| 422 | + angular.element(self.$window).on('blur', self.windowBlurHandler); |
| 423 | + |
| 424 | + $scope.$on('$destroy', function() { |
| 425 | + angular.element(self.$window).off('blur', self.windowBlurHandler); |
| 426 | + }); |
418 | 427 | }
|
419 | 428 |
|
420 | 429 | $scope.$on('md-calendar-close', function() {
|
|
643 | 652 | }
|
644 | 653 |
|
645 | 654 | if (this.calendarPane.parentNode) {
|
646 |
| - // Use native DOM removal because we do not want any of the angular state of this element |
647 |
| - // to be disposed. |
| 655 | + // Use native DOM removal because we do not want any of the |
| 656 | + // angular state of this element to be disposed. |
648 | 657 | this.calendarPane.parentNode.removeChild(this.calendarPane);
|
649 | 658 | }
|
650 | 659 | };
|
|
654 | 663 | * @param {Event} event
|
655 | 664 | */
|
656 | 665 | DatePickerCtrl.prototype.openCalendarPane = function(event) {
|
657 |
| - if (!this.isCalendarOpen && !this.isDisabled) { |
| 666 | + if (!this.isCalendarOpen && !this.isDisabled && !this.inputFocusedOnWindowBlur) { |
658 | 667 | this.isCalendarOpen = this.isOpen = true;
|
659 | 668 | this.calendarPaneOpenedFrom = event.target;
|
660 | 669 |
|
|
754 | 763 | this.$scope.$digest();
|
755 | 764 | }
|
756 | 765 | };
|
| 766 | + |
| 767 | + /** |
| 768 | + * Handles the event when the user navigates away from the current tab. Keeps track of |
| 769 | + * whether the input was focused when the event happened, in order to prevent the calendar |
| 770 | + * from re-opening. |
| 771 | + */ |
| 772 | + DatePickerCtrl.prototype.handleWindowBlur = function() { |
| 773 | + this.inputFocusedOnWindowBlur = document.activeElement === this.inputElement; |
| 774 | + }; |
757 | 775 | })();
|
0 commit comments