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

feat(datepicker): allow date strings as the source for ng-model #9554

Merged
merged 1 commit into from Feb 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/components/datepicker/js/datepickerDirective.js
Expand Up @@ -18,7 +18,7 @@
* @name mdDatepicker
* @module material.components.datepicker
*
* @param {Date} ng-model The component's model. Expects a JavaScript Date object.
* @param {Date} ng-model The component's model. Expects either a JavaScript Date object or a value that can be parsed into one (e.g. a ISO 8601 string).
* @param {Object=} ng-model-options Allows tuning of the way in which `ng-model` is being updated. Also allows
* for a timezone to be specified. <a href="https://docs.angularjs.org/api/ng/directive/ngModelOptions#usage">Read more at the ngModelOptions docs.</a>
* @param {expression=} ng-change Expression evaluated when the model value changes.
Expand Down Expand Up @@ -444,9 +444,18 @@

// Responds to external changes to the model value.
self.ngModelCtrl.$formatters.push(function(value) {
var parsedValue = angular.isDefined(value) ? Date.parse(value) : null;

// `parsedValue` is the time since epoch if valid or `NaN` if invalid.
if (!isNaN(parsedValue) && angular.isNumber(parsedValue)) {
value = new Date(parsedValue);
}

if (value && !(value instanceof Date)) {
throw Error('The ng-model for md-datepicker must be a Date instance. ' +
'Currently the model is a: ' + (typeof value));
throw Error(
'The ng-model for md-datepicker must be a Date instance or a value ' +
'that can be parsed into a date. Currently the model is of type: ' + typeof value
);
}

self.onExternalChange(value);
Expand Down
17 changes: 12 additions & 5 deletions src/components/datepicker/js/datepickerDirective.spec.js
Expand Up @@ -105,22 +105,29 @@ describe('md-datepicker', function() {
expect(controller.inputElement.placeholder).toBe('Fancy new placeholder');
});

it('should throw an error when the model is not a date', function() {
it('should forward the aria-label to the generated input', function() {
createDatepickerInstance('<md-datepicker ng-model="myDate" aria-label="Enter a date"></md-datepicker>');
expect(controller.ngInputElement.attr('aria-label')).toBe('Enter a date');
});

it('should throw an error when the model cannot be parsed into a date', function() {
expect(function() {
pageScope.myDate = '2015-01-01';
pageScope.myDate = 'Frodo Baggins';
pageScope.$apply();
}).toThrowError('The ng-model for md-datepicker must be a Date instance. ' +
'Currently the model is a: string');
}).toThrowError('The ng-model for md-datepicker must be a Date instance or a value ' +
'that can be parsed into a date. Currently the model is of type: string');
});

it('should support null and undefined values', function() {
it('should support null, undefined and values that can be parsed into a date', function() {
expect(function() {
pageScope.myDate = null;
pageScope.$apply();

pageScope.myDate = undefined;
pageScope.$apply();

pageScope.myDate = '2016-09-08';
pageScope.$apply();
}).not.toThrow();
});

Expand Down