diff --git a/src/components/datepicker/js/datepickerDirective.js b/src/components/datepicker/js/datepickerDirective.js index cba9caa7af0..050e69771f0 100644 --- a/src/components/datepicker/js/datepickerDirective.js +++ b/src/components/datepicker/js/datepickerDirective.js @@ -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. Read more at the ngModelOptions docs. * @param {expression=} ng-change Expression evaluated when the model value changes. @@ -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); diff --git a/src/components/datepicker/js/datepickerDirective.spec.js b/src/components/datepicker/js/datepickerDirective.spec.js index 8a591ed1639..38b045b4796 100644 --- a/src/components/datepicker/js/datepickerDirective.spec.js +++ b/src/components/datepicker/js/datepickerDirective.spec.js @@ -105,15 +105,20 @@ 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(''); + 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(); @@ -121,6 +126,8 @@ describe('md-datepicker', function() { pageScope.myDate = undefined; pageScope.$apply(); + pageScope.myDate = '2016-09-08'; + pageScope.$apply(); }).not.toThrow(); });