diff --git a/src/lib/datepicker/calendar.html b/src/lib/datepicker/calendar.html
index ab0532718bc..5bed9b3e0cf 100644
--- a/src/lib/datepicker/calendar.html
+++ b/src/lib/datepicker/calendar.html
@@ -48,7 +48,8 @@
[activeDate]="_activeDate"
[selected]="selected"
[dateFilter]="_dateFilterForViews"
- (selectedChange)="_dateSelected($event)">
+ (selectedChange)="_dateSelected($event)"
+ (userSelection)="_userSelected()">
implements AfterContentInit, OnDestroy {
/** Emits when the currently selected date changes. */
@Output() selectedChange = new EventEmitter();
+ /** Emits when any date is selected. */
+ @Output() userSelection = new EventEmitter();
+
/** Date filter for the month and year views. */
_dateFilterForViews = (date: D) => {
return !!date &&
@@ -159,6 +162,10 @@ export class MdCalendar implements AfterContentInit, OnDestroy {
}
}
+ _userSelected(): void {
+ this.userSelection.emit();
+ }
+
/** Handles month selection in the year view. */
_monthSelected(month: D): void {
this._activeDate = month;
diff --git a/src/lib/datepicker/datepicker-content.html b/src/lib/datepicker/datepicker-content.html
index 0f3a70ec7df..90fcc91b609 100644
--- a/src/lib/datepicker/datepicker-content.html
+++ b/src/lib/datepicker/datepicker-content.html
@@ -6,5 +6,6 @@
[maxDate]="datepicker._maxDate"
[dateFilter]="datepicker._dateFilter"
[selected]="datepicker._selected"
- (selectedChange)="datepicker._selectAndClose($event)">
+ (selectedChange)="datepicker._select($event)"
+ (userSelection)="datepicker.close()">
diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts
index d1f14cde955..9b608bd72e6 100644
--- a/src/lib/datepicker/datepicker.spec.ts
+++ b/src/lib/datepicker/datepicker.spec.ts
@@ -189,6 +189,30 @@ describe('MdDatepicker', () => {
});
});
+ it('clicking the currently selected date should close the calendar ' +
+ 'without firing selectedChanged', () => {
+ const selectedChangedSpy =
+ spyOn(testComponent.datepicker.selectedChanged, 'emit').and.callThrough();
+ for (let changeCount = 1; changeCount < 3; changeCount++) {
+ const currentDay = changeCount;
+ testComponent.datepicker.open();
+ fixture.detectChanges();
+
+ expect(document.querySelector('md-datepicker-content')).not.toBeNull();
+ expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, currentDay));
+
+ let cells = document.querySelectorAll('.mat-calendar-body-cell');
+ dispatchMouseEvent(cells[1], 'click');
+ fixture.detectChanges();
+ }
+
+ fixture.whenStable().then(() => {
+ expect(selectedChangedSpy.calls.count()).toEqual(1);
+ expect(document.querySelector('md-dialog-container')).toBeNull();
+ expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 2));
+ });
+ });
+
it('startAt should fallback to input value', () => {
expect(testComponent.datepicker.startAt).toEqual(new Date(2020, JAN, 1));
});
@@ -361,7 +385,7 @@ describe('MdDatepicker', () => {
expect(testComponent.datepickerInput.value).toBeNull();
let selected = new Date(2017, JAN, 1);
- testComponent.datepicker._selectAndClose(selected);
+ testComponent.datepicker._select(selected);
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -388,7 +412,7 @@ describe('MdDatepicker', () => {
expect(inputEl.classList).toContain('ng-pristine');
- testComponent.datepicker._selectAndClose(new Date(2017, JAN, 1));
+ testComponent.datepicker._select(new Date(2017, JAN, 1));
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -434,7 +458,7 @@ describe('MdDatepicker', () => {
expect(inputEl.classList).toContain('ng-untouched');
- testComponent.datepicker._selectAndClose(new Date(2017, JAN, 1));
+ testComponent.datepicker._select(new Date(2017, JAN, 1));
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -478,7 +502,7 @@ describe('MdDatepicker', () => {
expect(testComponent.datepickerInput.value).toBeNull();
let selected = new Date(2017, JAN, 1);
- testComponent.datepicker._selectAndClose(selected);
+ testComponent.datepicker._select(selected);
fixture.detectChanges();
expect(testComponent.formControl.value).toEqual(selected);
diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts
index 854210cbf77..29ab0c40afa 100644
--- a/src/lib/datepicker/datepicker.ts
+++ b/src/lib/datepicker/datepicker.ts
@@ -224,14 +224,13 @@ export class MdDatepicker implements OnDestroy {
}
}
- /** Selects the given date and closes the currently open popup or dialog. */
- _selectAndClose(date: D): void {
+ /** Selects the given date */
+ _select(date: D): void {
let oldValue = this._selected;
this._selected = date;
if (!this._dateAdapter.sameDate(oldValue, this._selected)) {
this.selectedChanged.emit(date);
}
- this.close();
}
/**
diff --git a/src/lib/datepicker/month-view.ts b/src/lib/datepicker/month-view.ts
index 5d15ae7c4bc..dcae6a54f40 100644
--- a/src/lib/datepicker/month-view.ts
+++ b/src/lib/datepicker/month-view.ts
@@ -67,6 +67,9 @@ export class MdMonthView implements AfterContentInit {
/** Emits when a new date is selected. */
@Output() selectedChange = new EventEmitter();
+ /** Emits when any date is selected. */
+ @Output() userSelection = new EventEmitter();
+
/** The label for this month (e.g. "January 2017"). */
_monthLabel: string;
@@ -116,12 +119,15 @@ export class MdMonthView implements AfterContentInit {
/** Handles when a new date is selected. */
_dateSelected(date: number) {
- if (this._selectedDate == date) {
- return;
+ if (this._selectedDate != date) {
+ const selectedYear = this._dateAdapter.getYear(this.activeDate);
+ const selectedMonth = this._dateAdapter.getMonth(this.activeDate);
+ const selectedDate = this._dateAdapter.createDate(selectedYear, selectedMonth, date);
+
+ this.selectedChange.emit(selectedDate);
}
- this.selectedChange.emit(this._dateAdapter.createDate(
- this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate),
- date));
+
+ this.userSelection.emit();
}
/** Initializes this month view. */