diff --git a/src/datepicker/datepicker.js b/src/datepicker/datepicker.js
index a98b48dc7e..9b7d48d53e 100644
--- a/src/datepicker/datepicker.js
+++ b/src/datepicker/datepicker.js
@@ -18,7 +18,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
shortcutPropagation: false
})
-.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$timeout', '$log', 'dateFilter', 'datepickerConfig', function($scope, $attrs, $parse, $interpolate, $timeout, $log, dateFilter, datepickerConfig) {
+.controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$log', 'dateFilter', 'datepickerConfig', function($scope, $attrs, $parse, $interpolate, $log, dateFilter, datepickerConfig) {
var self = this,
ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl;
@@ -161,9 +161,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
$scope.keys = { 13:'enter', 32:'space', 33:'pageup', 34:'pagedown', 35:'end', 36:'home', 37:'left', 38:'up', 39:'right', 40:'down' };
var focusElement = function() {
- $timeout(function() {
- self.element[0].focus();
- }, 0 , false);
+ self.element[0].focus();
};
// Listen for focus requests from popup directive
@@ -460,8 +458,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
showButtonBar: true
})
-.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig',
-function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig) {
+.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'dateParser', 'datepickerPopupConfig', '$timeout',
+function ($compile, $parse, $document, $position, dateFilter, dateParser, datepickerPopupConfig, $timeout) {
return {
restrict: 'EA',
require: 'ngModel',
@@ -517,7 +515,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
var popupEl = angular.element('
');
popupEl.attr({
'ng-model': 'date',
- 'ng-change': 'dateSelection()'
+ 'ng-change': 'dateSelection(date)'
});
function cameltoDash( string ){
@@ -661,30 +659,41 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
}
};
- var keydown = function(evt, noApply) {
- scope.keydown(evt);
+ var inputKeydownBind = function(evt) {
+ if (evt.which === 27 && scope.isOpen) {
+ evt.preventDefault();
+ evt.stopPropagation();
+ scope.$apply(function() {
+ scope.isOpen = false;
+ });
+ element[0].focus();
+ } else if (evt.which === 40 && !scope.isOpen) {
+ evt.preventDefault();
+ evt.stopPropagation();
+ scope.$apply(function() {
+ scope.isOpen = true;
+ });
+ }
};
- element.bind('keydown', keydown);
+ element.bind('keydown', inputKeydownBind);
scope.keydown = function(evt) {
if (evt.which === 27) {
- evt.preventDefault();
- if (scope.isOpen) {
- evt.stopPropagation();
- }
- scope.close();
- } else if (evt.which === 40 && !scope.isOpen) {
- scope.isOpen = true;
+ scope.isOpen = false;
+ element[0].focus();
}
};
scope.$watch('isOpen', function(value) {
if (value) {
- scope.$broadcast('datepicker.focus');
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
scope.position.top = scope.position.top + element.prop('offsetHeight');
$document.bind('click', documentClickBind);
+
+ $timeout(function() {
+ scope.$broadcast('datepicker.focus');
+ }, 0, false);
} else {
$document.unbind('click', documentClickBind);
}
@@ -719,8 +728,14 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
}
scope.$on('$destroy', function() {
+ if (scope.isOpen === true) {
+ scope.$apply(function() {
+ scope.isOpen = false;
+ });
+ }
+
$popup.remove();
- element.unbind('keydown', keydown);
+ element.unbind('keydown', inputKeydownBind);
$document.unbind('click', documentClickBind);
});
}
@@ -732,12 +747,6 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
restrict:'EA',
replace: true,
transclude: true,
- templateUrl: 'template/datepicker/popup.html',
- link:function (scope, element, attrs) {
- element.bind('click', function(event) {
- event.preventDefault();
- event.stopPropagation();
- });
- }
+ templateUrl: 'template/datepicker/popup.html'
};
});
diff --git a/src/datepicker/test/datepicker.spec.js b/src/datepicker/test/datepicker.spec.js
index 09aa37e26b..3d60c259eb 100644
--- a/src/datepicker/test/datepicker.spec.js
+++ b/src/datepicker/test/datepicker.spec.js
@@ -1185,7 +1185,7 @@ describe('datepicker directive', function () {
}));
it('does not to display datepicker initially', function() {
- expect(dropdownEl).toBeHidden();
+ expect(dropdownEl.length).toBe(0);
});
it('to display the correct value in input', function() {
@@ -1194,18 +1194,20 @@ describe('datepicker directive', function () {
});
describe('initially opened', function () {
+ var wrapElement;
+
beforeEach(inject(function(_$document_, _$sniffer_) {
$document = _$document_;
$sniffer = _$sniffer_;
$rootScope.isopen = true;
$rootScope.date = new Date('September 30, 2010 15:30:00');
- var wrapElement = $compile('')($rootScope);
+ wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
it('datepicker is displayed', function() {
- expect(dropdownEl).not.toBeHidden();
+ expect(dropdownEl.length).toBe(1);
});
it('renders the calendar correctly', function() {
@@ -1240,10 +1242,11 @@ describe('datepicker directive', function () {
});
it('closes the dropdown when a day is clicked', function() {
- expect(dropdownEl.css('display')).not.toBe('none');
+ expect(dropdownEl.length).toBe(1);
clickOption(17);
- expect(dropdownEl.css('display')).toBe('none');
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
});
it('updates the model & calendar when input value changes', function() {
@@ -1265,10 +1268,11 @@ describe('datepicker directive', function () {
});
it('closes when click outside of calendar', function() {
- expect(dropdownEl).not.toBeHidden();
+ expect(dropdownEl.length).toBe(1);
$document.find('body').click();
- expect(dropdownEl.css('display')).toBe('none');
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
});
it('sets `ng-invalid` for invalid input', function() {
@@ -1303,41 +1307,36 @@ describe('datepicker directive', function () {
});
it('returns to the input when ESC key is pressed in the popup and closes', function() {
- expect(dropdownEl).not.toBeHidden();
+ expect(dropdownEl.length).toBe(1);
dropdownEl.find('button').eq(0).focus();
expect(document.activeElement.tagName).toBe('BUTTON');
triggerKeyDown(dropdownEl, 'esc');
- expect(dropdownEl).toBeHidden();
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
expect(document.activeElement.tagName).toBe('INPUT');
});
it('returns to the input when ESC key is pressed in the input and closes', function() {
- expect(dropdownEl).not.toBeHidden();
+ expect(dropdownEl.length).toBe(1);
dropdownEl.find('button').eq(0).focus();
expect(document.activeElement.tagName).toBe('BUTTON');
triggerKeyDown(inputEl, 'esc');
$rootScope.$digest();
- expect(dropdownEl).toBeHidden();
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
expect(document.activeElement.tagName).toBe('INPUT');
});
it('stops the ESC key from propagating if the dropdown is open, but not when closed', function() {
- expect(dropdownEl).not.toBeHidden();
-
- dropdownEl.find('button').eq(0).focus();
- expect(document.activeElement.tagName).toBe('BUTTON');
-
var documentKey = -1;
var getKey = function(evt) { documentKey = evt.which; };
$document.bind('keydown', getKey);
triggerKeyDown(inputEl, 'esc');
- $rootScope.$digest();
- expect(dropdownEl).toBeHidden();
expect(documentKey).toBe(-1);
triggerKeyDown(inputEl, 'esc');
@@ -1357,7 +1356,7 @@ describe('datepicker directive', function () {
$rootScope.date = new Date('September 30, 2010 15:30:00');
var wrapElement = $compile('
')($rootScope);
+ 'datepicker-popup is-open="isopen">
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
@@ -1420,7 +1419,7 @@ describe('datepicker directive', function () {
it('works as date', function() {
setupInputWithType('date');
- expect(dropdownEl).toBeHidden();
+ expect(dropdownEl.length).toBe(1);
expect(inputEl.val()).toBe('2010-09-30');
changeInputValueTo(inputEl, '1980-03-05');
@@ -1482,7 +1481,7 @@ describe('datepicker directive', function () {
function setupInputWithType(type) {
var wrapElement = $compile('
')($rootScope);
+ type + '" ng-model="date" datepicker-popup is-open="isopen">
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}
@@ -1594,32 +1593,36 @@ describe('datepicker directive', function () {
});
describe('toggles programatically by `open` attribute', function () {
+ var wrapElement;
+
beforeEach(inject(function() {
$rootScope.open = true;
- var wrapElement = $compile('
')($rootScope);
+ wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
it('to display initially', function() {
- expect(dropdownEl.css('display')).not.toBe('none');
+ expect(dropdownEl.length).toBe(1);
});
it('to close / open from scope variable', function() {
- expect(dropdownEl.css('display')).not.toBe('none');
+ expect(dropdownEl.length).toBe(1);
$rootScope.open = false;
$rootScope.$digest();
- expect(dropdownEl.css('display')).toBe('none');
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
$rootScope.open = true;
$rootScope.$digest();
- expect(dropdownEl.css('display')).not.toBe('none');
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(1);
});
});
describe('custom format', function () {
beforeEach(inject(function() {
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
@@ -1644,7 +1647,7 @@ describe('datepicker directive', function () {
describe('dynamic custom format', function () {
beforeEach(inject(function() {
$rootScope.format = 'dd-MMMM-yyyy';
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
@@ -1686,16 +1689,18 @@ describe('datepicker directive', function () {
});
describe('`close-on-date-selection` attribute', function () {
+ var wrapElement;
beforeEach(inject(function() {
$rootScope.close = false;
- var wrapElement = $compile('
')($rootScope);
+ wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
it('does not close the dropdown when a day is clicked', function() {
clickOption(17);
- expect(dropdownEl.css('display')).not.toBe('none');
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(1);
});
});
@@ -1708,16 +1713,18 @@ describe('datepicker directive', function () {
}
describe('', function () {
+ var wrapElement;
+
beforeEach(inject(function() {
$rootScope.isopen = true;
- var wrapElement = $compile('
')($rootScope);
+ wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
assignButtonBar();
}));
it('should exist', function() {
- expect(dropdownEl).not.toBeHidden();
+ expect(dropdownEl.length).toBe(1);
expect(dropdownEl.find('li').length).toBe(2);
});
@@ -1763,7 +1770,8 @@ describe('datepicker directive', function () {
it('should have a button to close calendar', function() {
buttons.eq(2).click();
- expect(dropdownEl).toBeHidden();
+ assignElements(wrapElement);
+ expect(dropdownEl.length).toBe(0);
});
});
@@ -1771,7 +1779,7 @@ describe('datepicker directive', function () {
it('should change text from attributes', function() {
$rootScope.clearText = 'Null it!';
$rootScope.close = 'Close';
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
assignButtonBar();
@@ -1783,14 +1791,14 @@ describe('datepicker directive', function () {
it('should remove bar', function() {
$rootScope.showBar = false;
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
expect(dropdownEl.find('li').length).toBe(1);
});
it('should hide weeks column on popup', function() {
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
@@ -1802,7 +1810,7 @@ describe('datepicker directive', function () {
});
it('should show weeks column on popup', function() {
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
@@ -1817,7 +1825,7 @@ describe('datepicker directive', function () {
describe('`ng-change`', function() {
beforeEach(inject(function() {
$rootScope.changeHandler = jasmine.createSpy('changeHandler');
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
assignButtonBar();
@@ -1869,7 +1877,7 @@ describe('datepicker directive', function () {
beforeEach(inject(function() {
$rootScope.changeHandler = jasmine.createSpy('changeHandler');
$rootScope.date = new Date('09/16/2010');
- var wrapElement = $compile('
')($rootScope);
+ var wrapElement = $compile('
')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);
}));
@@ -1903,7 +1911,7 @@ describe('datepicker directive', function () {
var $body = $document.find('body'),
bodyLength = $body.children().length,
elm = angular.element(
- '
'
+ '
'
);
$compile(elm)($rootScope);
$rootScope.$digest();
@@ -1916,7 +1924,7 @@ describe('datepicker directive', function () {
bodyLength = $body.children().length,
isolatedScope = $rootScope.$new(),
elm = angular.element(
- '
'
+ '
'
);
$compile(elm)(isolatedScope);
isolatedScope.$digest();
@@ -1932,7 +1940,7 @@ describe('datepicker directive', function () {
angular.extend(originalConfig, datepickerConfig);
datepickerConfig.showWeeks = false;
- var wrapElement = $compile('