Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(datepicker): implements alternative format support
Browse files Browse the repository at this point in the history
- Adds support for multiple input formats

Closes #4951
Closes #4952
  • Loading branch information
davious authored and wesleycho committed Nov 26, 2015
1 parent f3d4dc2 commit 8bfeda0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 4 deletions.
22 changes: 20 additions & 2 deletions src/datepicker/datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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 = {};

Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/datepicker/docs/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h4>Popup</h4>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" is-open="popup1.opened" min-date="minDate" max-date="maxDate" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" is-open="popup1.opened" min-date="minDate" max-date="maxDate" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" alt-input-formats="altInputFormats" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
Expand All @@ -40,7 +40,7 @@ <h4>Popup</h4>
</div>
<div class="row">
<div class="col-md-6">
<label>Format:</label> <select class="form-control" ng-model="format" ng-options="f for f in formats"><option></option></select>
<label>Format: <span class="muted-text">(manual alternate <em>{{altInputFormats[0]}}</em>)</span></label> <select class="form-control" ng-model="format" ng-options="f for f in formats"><option></option></select>
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions src/datepicker/docs/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/datepicker/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
45 changes: 45 additions & 0 deletions src/datepicker/test/datepicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<div><input ng-model="date" uib-datepicker-popup is-open="true"></div>')($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('<div><input ng-model="date" uib-datepicker-popup="MMMM d yyyy" alt-input-formats="[\'M!/d!/yyyy\']" is-open="true"></div>')($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() {
Expand Down

0 comments on commit 8bfeda0

Please sign in to comment.