diff --git a/src/datepicker/datepicker.js b/src/datepicker/datepicker.js
index b20a484d3f..a66465147d 100644
--- a/src/datepicker/datepicker.js
+++ b/src/datepicker/datepicker.js
@@ -539,7 +539,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
closeOnDateSelection: true,
appendToBody: false,
showButtonBar: true,
- onOpenFocus: true
+ onOpenFocus: true,
+ altInputFormats: []
})
.controller('UibDatepickerPopupController', ['$scope', '$element', '$attrs', '$compile', '$parse', '$document', '$rootScope', '$uibPosition', 'dateFilter', 'uibDateParser', 'uibDatepickerPopupConfig', '$timeout',
@@ -549,7 +550,7 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
isHtml5DateInput = false;
var dateFormat, closeOnDateSelection, appendToBody, onOpenFocus,
datepickerPopupTemplateUrl, datepickerTemplateUrl, popupEl, datepickerEl,
- ngModel, $popup;
+ ngModel, $popup, altInputFormats;
scope.watchData = {};
@@ -560,6 +561,7 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
onOpenFocus = angular.isDefined(attrs.onOpenFocus) ? scope.$parent.$eval(attrs.onOpenFocus) : datepickerPopupConfig.onOpenFocus;
datepickerPopupTemplateUrl = angular.isDefined(attrs.datepickerPopupTemplateUrl) ? attrs.datepickerPopupTemplateUrl : datepickerPopupConfig.datepickerPopupTemplateUrl;
datepickerTemplateUrl = angular.isDefined(attrs.datepickerTemplateUrl) ? attrs.datepickerTemplateUrl : datepickerPopupConfig.datepickerTemplateUrl;
+ altInputFormats = angular.isDefined(attrs.altInputFormats) ? scope.$parent.$eval(attrs.altInputFormats) : datepickerPopupConfig.altInputFormats;
scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
@@ -811,6 +813,14 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
if (angular.isString(viewValue)) {
var date = dateParser.parse(viewValue, dateFormat, scope.date);
+ if (isNaN(date)) {
+ for (var i = 0; i < altInputFormats.length; i++) {
+ date = dateParser.parse(viewValue, altInputFormats[i], scope.date);
+ if (!isNaN(date)) {
+ break;
+ }
+ }
+ }
if (isNaN(date)) {
return undefined;
}
@@ -842,6 +852,14 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
if (angular.isString(value)) {
var date = dateParser.parse(value, dateFormat);
+ if (isNaN(date)) {
+ for (var i = 0; i < altInputFormats.length; i++) {
+ date = dateParser.parse(value, altInputFormats[i]);
+ if (!isNaN(date)) {
+ break;
+ }
+ }
+ }
return !isNaN(date);
}
diff --git a/src/datepicker/docs/demo.html b/src/datepicker/docs/demo.html
index 7414f1847f..c97f00a971 100644
--- a/src/datepicker/docs/demo.html
+++ b/src/datepicker/docs/demo.html
@@ -22,7 +22,7 @@
Popup
-
+
diff --git a/src/datepicker/docs/demo.js b/src/datepicker/docs/demo.js
index 590b759fbb..aac7f0b2d3 100644
--- a/src/datepicker/docs/demo.js
+++ b/src/datepicker/docs/demo.js
@@ -39,6 +39,7 @@ angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function ($
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
+ $scope.altInputFormats = ['M!/d!/yyyy'];
$scope.popup1 = {
opened: false
diff --git a/src/datepicker/docs/readme.md b/src/datepicker/docs/readme.md
index c72f9a2e75..daa9da3285 100644
--- a/src/datepicker/docs/readme.md
+++ b/src/datepicker/docs/readme.md
@@ -144,6 +144,10 @@ Options for the uib-datepicker must be passed as JSON using the `datepicker-opti
_(Default: `yyyy-MM-dd`)_ -
The format for displayed dates. This string can take string literals by surrounding the value with single quotes, i.e. `yyyy-MM-dd h 'o\'clock'`
+ * `alt-input-formats`
+ _(Default: `[]`)_:
+ A list of alternate formats acceptable for manual entry.
+
### Keyboard support ###
Depending on datepicker's current mode, the date may refer either to day, month or year. Accordingly, the term view refers either to a month, year or year range.
diff --git a/src/datepicker/test/datepicker.spec.js b/src/datepicker/test/datepicker.spec.js
index e9384a5d4a..972bb57a8c 100644
--- a/src/datepicker/test/datepicker.spec.js
+++ b/src/datepicker/test/datepicker.spec.js
@@ -2339,6 +2339,51 @@ describe('datepicker', function() {
});
});
+ describe('altInputFormats', function() {
+ describe('datepickerPopupConfig.altInputFormats', function() {
+ var originalConfig = {};
+ beforeEach(inject(function(uibDatepickerPopupConfig) {
+ angular.extend(originalConfig, uibDatepickerPopupConfig);
+ uibDatepickerPopupConfig.datepickerPopup = 'MM-dd-yyyy';
+ uibDatepickerPopupConfig.altInputFormats = ['M!/d!/yyyy'];
+
+ var wrapElement = $compile('
')($rootScope);
+ $rootScope.$digest();
+ assignElements(wrapElement);
+ }));
+
+ afterEach(inject(function(uibDatepickerPopupConfig) {
+ // return it to the original state
+ angular.extend(uibDatepickerPopupConfig, originalConfig);
+ }));
+
+ it('changes date format', function() {
+ changeInputValueTo(inputEl, '11/8/1980');
+
+ expect($rootScope.date.getFullYear()).toEqual(1980);
+ expect($rootScope.date.getMonth()).toEqual(10);
+ expect($rootScope.date.getDate()).toEqual(8);
+ });
+ });
+
+ describe('attribute `alt-input-formats`', function() {
+ beforeEach(function() {
+ $rootScope.date = new Date('November 9, 1980');
+ var wrapElement = $compile('
')($rootScope);
+ $rootScope.$digest();
+ assignElements(wrapElement);
+ });
+
+ it('should accept alternate input formats', function() {
+ changeInputValueTo(inputEl, '11/8/1980');
+
+ expect($rootScope.date.getFullYear()).toEqual(1980);
+ expect($rootScope.date.getMonth()).toEqual(10);
+ expect($rootScope.date.getDate()).toEqual(8);
+ });
+ });
+ });
+
describe('pass through attributes', function() {
var wrapElement;
describe('formatting', function() {