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

feat(datepicker): alt-input-formats #4952

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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