Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(datepicker): gray out filtered years in multi-year view #9563

Merged
merged 6 commits into from
Jan 25, 2018
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion src/demo-app/datepicker/datepicker-demo.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h2>Options</h2>
<p>
<mat-checkbox [(ngModel)]="touch">Use touch UI</mat-checkbox>
<mat-checkbox [(ngModel)]="filterOdd">Filter odd months and dates</mat-checkbox>
<mat-checkbox [(ngModel)]="filterOdd">Filter odd years, months and dates</mat-checkbox>
<mat-checkbox [(ngModel)]="yearView">Start in year view</mat-checkbox>
<mat-checkbox [(ngModel)]="datepickerDisabled">Disable datepicker</mat-checkbox>
<mat-checkbox [(ngModel)]="inputDisabled">Disable input</mat-checkbox>
Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/datepicker/datepicker-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class DatepickerDemo {
lastDateInput: Date | null;
lastDateChange: Date | null;

dateFilter = (date: Date) => date.getMonth() % 2 == 1 && date.getDate() % 2 == 0;
dateFilter = (date: Date) => date.getFullYear() % 2 == 0 && date.getMonth() % 2 == 1 && date.getDate() % 2 == 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be simplified to !date.getFullYear() && date.getMonth() % 2 == 1 && !date.getDate() % 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assume you meant: !date.getFullYear() % 2 && date.getMonth() % 2 && !date.getDate() % 2;?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups, yes. Bad copy/paste :D


onDateInput = (e: MatDatepickerInputEvent<Date>) => this.lastDateInput = e.value;
onDateChange = (e: MatDatepickerInputEvent<Date>) => this.lastDateChange = e.value;
Expand Down
35 changes: 35 additions & 0 deletions src/lib/datepicker/multi-year-view.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('MatMultiYearView', () => {

// Test components.
StandardMultiYearView,
MultiYearViewWithDateFilter,
],
});

Expand Down Expand Up @@ -71,6 +72,27 @@ describe('MatMultiYearView', () => {
expect(cellEls[1].classList).toContain('mat-calendar-body-active');
});
});

describe('multi year view with date filter', () => {
let fixture: ComponentFixture<MultiYearViewWithDateFilter>;
let testComponent: MultiYearViewWithDateFilter;
let multiYearViewNativeElement: Element;

beforeEach(() => {
fixture = TestBed.createComponent(MultiYearViewWithDateFilter);
fixture.detectChanges();

let multiYearViewDebugElement = fixture.debugElement.query(By.directive(MatMultiYearView));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

multiYearViewNativeElement = multiYearViewDebugElement.nativeElement;
testComponent = fixture.componentInstance;
});

it('should disable years with no enabled days', () => {
let cells = multiYearViewNativeElement.querySelectorAll('.mat-calendar-body-cell');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

expect(cells[0].classList).not.toContain('mat-calendar-body-disabled');
expect(cells[1].classList).toContain('mat-calendar-body-disabled');
});
});
});


Expand All @@ -84,3 +106,16 @@ class StandardMultiYearView {

@ViewChild(MatYearView) yearView: MatYearView<Date>;
}

@Component({
template: `<mat-multi-year-view [activeDate]="activeDate" [dateFilter]="dateFilter"></mat-multi-year-view>`
})
class MultiYearViewWithDateFilter {
activeDate = new Date(2017, JAN, 1);
dateFilter(date: Date) {
if (date.getFullYear() == 2017) {
Copy link
Contributor

@rafaelss95 rafaelss95 Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about return date.getFullYear() !== 2017;?

return false;
}
return true;
}
}
39 changes: 29 additions & 10 deletions src/lib/datepicker/multi-year-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import {
Output,
ViewEncapsulation
} from '@angular/core';
import {DateAdapter} from '@angular/material/core';
import {MatCalendarCell} from './calendar-body';
import {createMissingDateImplError} from './datepicker-errors';
import { DateAdapter } from '@angular/material/core';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo

import { MatCalendarCell } from './calendar-body';
import { createMissingDateImplError } from './datepicker-errors';


export const yearsPerPage = 24;
Expand Down Expand Up @@ -47,9 +47,9 @@ export class MatMultiYearView<D> implements AfterContentInit {
set activeDate(value: D) {
let oldActiveDate = this._activeDate;
this._activeDate =
this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();
this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo

if (Math.floor(this._dateAdapter.getYear(oldActiveDate) / yearsPerPage) !=
Math.floor(this._dateAdapter.getYear(this._activeDate) / yearsPerPage)) {
Math.floor(this._dateAdapter.getYear(this._activeDate) / yearsPerPage)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed this one

this._init();
}
}
Expand Down Expand Up @@ -79,8 +79,8 @@ export class MatMultiYearView<D> implements AfterContentInit {
/** The year of the selected date. Null if the selected date is null. */
_selectedYear: number | null;

constructor(@Optional() public _dateAdapter: DateAdapter<D>,
private _changeDetectorRef: ChangeDetectorRef) {
constructor( @Optional() public _dateAdapter: DateAdapter<D>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo

private _changeDetectorRef: ChangeDetectorRef) {
if (!this._dateAdapter) {
throw createMissingDateImplError('DateAdapter');
}
Expand Down Expand Up @@ -112,9 +112,9 @@ export class MatMultiYearView<D> implements AfterContentInit {
_yearSelected(year: number) {
let month = this._dateAdapter.getMonth(this.activeDate);
let daysInMonth =
this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(year, month, 1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo

this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(year, month, 1));
this.selectedChange.emit(this._dateAdapter.createDate(year, month,
Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));
Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed this one

}

_getActiveCell(): number {
Expand All @@ -124,7 +124,26 @@ export class MatMultiYearView<D> implements AfterContentInit {
/** Creates an MatCalendarCell for the given year. */
private _createCellForYear(year: number) {
let yearName = this._dateAdapter.getYearName(this._dateAdapter.createDate(year, 0, 1));
return new MatCalendarCell(year, yearName, yearName, true);
return new MatCalendarCell(year, yearName, yearName, this._isYearEnabled(year));
}

/** Whether the given year is enabled. */
private _isYearEnabled(year: number) {
if (!this.dateFilter) {
return true;
}

let firstOfYear = this._dateAdapter.createDate(year, 0, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const


// If any date in the year is enabled count the year as enabled.
for (let date = firstOfYear; this._dateAdapter.getYear(date) == year;
date = this._dateAdapter.addCalendarDays(date, 1)) {
if (this.dateFilter(date)) {
return true;
}
}

return false;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/lib/datepicker/year-view.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ describe('MatYearView', () => {
testComponent = fixture.componentInstance;
});

it('should disabled months with no enabled days', () => {
it('should disable months with no enabled days', () => {
let cells = yearViewNativeElement.querySelectorAll('.mat-calendar-body-cell');
expect(cells[0].classList).not.toContain('mat-calendar-body-disabled');
expect(cells[1].classList).toContain('mat-calendar-body-disabled');
Expand Down