diff --git a/src/demo-app/datepicker/datepicker-demo.html b/src/demo-app/datepicker/datepicker-demo.html index faee6d1cb911..0ba2e16746d8 100644 --- a/src/demo-app/datepicker/datepicker-demo.html +++ b/src/demo-app/datepicker/datepicker-demo.html @@ -19,9 +19,8 @@

Work in progress, not ready for use.

- - + +

diff --git a/src/lib/datepicker/datepicker-input.ts b/src/lib/datepicker/datepicker-input.ts index e4426b0567fd..9f6cc473db33 100644 --- a/src/lib/datepicker/datepicker-input.ts +++ b/src/lib/datepicker/datepicker-input.ts @@ -32,12 +32,15 @@ export const MD_DATEPICKER_VALUE_ACCESSOR: any = { '[attr.aria-expanded]': '_datepicker?.opened || "false"', '[attr.aria-haspopup]': 'true', '[attr.aria-owns]': '_datepicker?.id', + '[min]': '_min?.toNativeDate()', + '[max]': '_max?.toNativeDate()', '(input)': '_onChange($event.target.value)', '(blur)': '_onTouched()', '(keydown)': '_onKeydown($event)', } }) export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor, OnDestroy { + /** The datepicker that this input is associated with. */ @Input() set mdDatepicker(value: MdDatepicker) { if (value) { @@ -47,6 +50,10 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor } _datepicker: MdDatepicker; + @Input() + set matDatepicker(value: MdDatepicker) { this.mdDatepicker = value; } + + /** The value of the input. */ @Input() get value(): SimpleDate { return this._value; @@ -58,8 +65,17 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor } private _value: SimpleDate; + /** The minimum valid date. */ @Input() - set matDatepicker(value: MdDatepicker) { this.mdDatepicker = value; } + get min(): SimpleDate { return this._min; } + set min(value: SimpleDate) { this._min = this._locale.parseDate(value); } + private _min: SimpleDate; + + /** The maximum valid date. */ + @Input() + get max(): SimpleDate { return this._max; } + set max(value: SimpleDate) { this._max = this._locale.parseDate(value); } + private _max: SimpleDate; _onChange = (value: any) => {}; @@ -89,6 +105,10 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor } } + /** + * Gets the element that the datepicker popup should be connected to. + * @return The element to connect the popup to. + */ getPopupConnectionElementRef(): ElementRef { return this._mdInputContainer ? this._mdInputContainer.underlineRef : this._elementRef; } diff --git a/src/lib/datepicker/datepicker.html b/src/lib/datepicker/datepicker.html index bf5fffc2bbb3..68c4abcaf2a0 100644 --- a/src/lib/datepicker/datepicker.html +++ b/src/lib/datepicker/datepicker.html @@ -4,8 +4,8 @@ [class.mat-datepicker-touch]="touchUi" [class.mat-datepicker-non-touch]="!touchUi" [startAt]="startAt" - [minDate]="minDate" - [maxDate]="maxDate" + [minDate]="_minDate" + [maxDate]="_maxDate" [dateFilter]="dateFilter" [(selected)]="_selected"> diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 116126ee27e2..03f91edb4ecf 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -23,6 +23,7 @@ describe('MdDatepicker', () => { ], declarations: [ DatepickerWithFormControl, + DatepickerWithMinAndMax, DatepickerWithNgModel, DatepickerWithStartAt, DatepickerWithToggle, @@ -397,6 +398,28 @@ describe('MdDatepicker', () => { .toBe(true, 'popup should be attached to input-container underline'); }); }); + + describe('datepicker with min and max dates', () => { + let fixture: ComponentFixture; + let testComponent: DatepickerWithMinAndMax; + + beforeEach(async(() => { + fixture = TestBed.createComponent(DatepickerWithMinAndMax); + fixture.detectChanges(); + + testComponent = fixture.componentInstance; + })); + + afterEach(async(() => { + testComponent.datepicker.close(); + fixture.detectChanges(); + })); + + it('should use min and max dates specified by the input', () => { + expect(testComponent.datepicker._minDate).toEqual(new SimpleDate(2010, 0, 1)); + expect(testComponent.datepicker._maxDate).toEqual(new SimpleDate(2020, 0, 1)); + }); + }); }); @@ -487,3 +510,14 @@ class InputContainerDatepicker { @ViewChild('d') datepicker: MdDatepicker; @ViewChild(MdDatepickerInput) datepickerInput: MdDatepickerInput; } + + +@Component({ + template: ` + + + `, +}) +class DatepickerWithMinAndMax { + @ViewChild('d') datepicker: MdDatepicker; +} diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts index ebb2664facd7..ec39254664ec 100644 --- a/src/lib/datepicker/datepicker.ts +++ b/src/lib/datepicker/datepicker.ts @@ -67,18 +67,6 @@ export class MdDatepicker implements OnDestroy { @Input() touchUi = false; - /** The minimum selectable date. */ - @Input() - get minDate(): SimpleDate { return this._minDate; }; - set minDate(date: SimpleDate) { this._minDate = this._locale.parseDate(date); } - private _minDate: SimpleDate; - - /** The maximum selectable date. */ - @Input() - get maxDate(): SimpleDate { return this._maxDate; }; - set maxDate(date: SimpleDate) { this._maxDate = this._locale.parseDate(date); } - private _maxDate: SimpleDate; - /** A function used to filter which dates are selectable. */ @Input() dateFilter: (date: SimpleDate) => boolean; @@ -101,6 +89,16 @@ export class MdDatepicker implements OnDestroy { this.close(); } + /** The minimum selectable date. */ + get _minDate(): SimpleDate { + return this._datepickerInput && this._datepickerInput.min; + } + + /** The maximum selectable date. */ + get _maxDate(): SimpleDate { + return this._datepickerInput && this._datepickerInput.max; + } + /** The calendar template. */ @ViewChild(TemplateRef) calendarTemplate: TemplateRef;