diff --git a/lib/core/src/datetimepicker/calendar.html b/lib/core/src/datetimepicker/calendar.html index 05916b1f..c64f359c 100644 --- a/lib/core/src/datetimepicker/calendar.html +++ b/lib/core/src/datetimepicker/calendar.html @@ -63,6 +63,7 @@ [interval]="timeInterval" [minDate]="minDate" [maxDate]="maxDate" + [dateFilter]="dateFilter" [selected]="_activeDate" (activeDateChange)="_onActiveDateChange($event)" (selectedChange)="_timeSelected($event)" diff --git a/lib/core/src/datetimepicker/calendar.ts b/lib/core/src/datetimepicker/calendar.ts index 2f534a7e..cb288bf6 100644 --- a/lib/core/src/datetimepicker/calendar.ts +++ b/lib/core/src/datetimepicker/calendar.ts @@ -39,6 +39,7 @@ import { first } from "rxjs/operators/first"; import { createMissingDateImplError } from "./datetimepicker-errors"; import { Subscription } from "rxjs/Subscription"; import { slideCalendar } from "./datetimepicker-animations"; +import { MatDatetimepickerFilterType } from "./datetimepicker-filtertype"; /** * A calendar that is used as part of the datepicker. @@ -119,7 +120,7 @@ export class MatDatetimepickerCalendar implements AfterContentInit, OnDestroy @Input() timeInterval: number = 1; /** A function used to filter which dates are selectable. */ - @Input() dateFilter: (date: D) => boolean; + @Input() dateFilter: (date: D, type: MatDatetimepickerFilterType) => boolean; /** Emits when the currently selected date changes. */ @Output() selectedChange = new EventEmitter(); @@ -127,7 +128,7 @@ export class MatDatetimepickerCalendar implements AfterContentInit, OnDestroy /** Date filter for the month and year views. */ _dateFilterForViews = (date: D) => { return !!date && - (!this.dateFilter || this.dateFilter(date)) && + (!this.dateFilter || this.dateFilter(date, MatDatetimepickerFilterType.DATE)) && (!this.minDate || this._adapter.compareDate(date, this.minDate) >= 0) && (!this.maxDate || this._adapter.compareDate(date, this.maxDate) <= 0); }; diff --git a/lib/core/src/datetimepicker/clock.ts b/lib/core/src/datetimepicker/clock.ts index d1bd9b08..0489a6c8 100644 --- a/lib/core/src/datetimepicker/clock.ts +++ b/lib/core/src/datetimepicker/clock.ts @@ -8,6 +8,7 @@ import { Output } from "@angular/core"; import { DatetimeAdapter } from "../adapter/datetime-adapter"; +import { MatDatetimepickerFilterType } from "./datetimepicker-filtertype"; export const CLOCK_RADIUS = 50; export const CLOCK_INNER_RADIUS = 27.5; @@ -99,7 +100,7 @@ export class MatDatetimepickerClock implements AfterContentInit { } /** A function used to filter which dates are selectable. */ - @Input() dateFilter: (date: D) => boolean; + @Input() dateFilter: (date: D, type: MatDatetimepickerFilterType) => boolean; @Input() interval: number = 1; @@ -226,7 +227,8 @@ export class MatDatetimepickerClock implements AfterContentInit { this._adapter.getDate(this.activeDate), i, 0); let enabled = (!this.minDate || this._adapter.compareDatetime(date, this.minDate) >= 0) && - (!this.maxDate || this._adapter.compareDatetime(date, this.maxDate) <= 0); + (!this.maxDate || this._adapter.compareDatetime(date, this.maxDate) <= 0) && + (!this.dateFilter || this.dateFilter(date, MatDatetimepickerFilterType.HOUR)); this._hours.push({ value: i, displayValue: i === 0 ? "00" : hourNames[i], @@ -246,7 +248,8 @@ export class MatDatetimepickerClock implements AfterContentInit { this._adapter.getDate(this.activeDate), this._adapter.getHour(this.activeDate), i); let enabled = (!this.minDate || this._adapter.compareDatetime(date, this.minDate) >= 0) && - (!this.maxDate || this._adapter.compareDatetime(date, this.maxDate) <= 0); + (!this.maxDate || this._adapter.compareDatetime(date, this.maxDate) <= 0) && + (!this.dateFilter || this.dateFilter(date, MatDatetimepickerFilterType.MINUTE)); this._minutes.push({ value: i, displayValue: i === 0 ? "00" : minuteNames[i], diff --git a/lib/core/src/datetimepicker/datetimepicker-filtertype.ts b/lib/core/src/datetimepicker/datetimepicker-filtertype.ts new file mode 100644 index 00000000..17ea4b21 --- /dev/null +++ b/lib/core/src/datetimepicker/datetimepicker-filtertype.ts @@ -0,0 +1,3 @@ +export enum MatDatetimepickerFilterType { + DATE, HOUR, MINUTE +} diff --git a/lib/core/src/datetimepicker/datetimepicker-input.ts b/lib/core/src/datetimepicker/datetimepicker-input.ts index ab7262bb..841a860e 100644 --- a/lib/core/src/datetimepicker/datetimepicker-input.ts +++ b/lib/core/src/datetimepicker/datetimepicker-input.ts @@ -35,6 +35,7 @@ import { import { Subscription } from "rxjs/Subscription"; import { MatDatetimepicker } from "./datetimepicker"; import { createMissingDateImplError } from "./datetimepicker-errors"; +import {MatDatetimepickerFilterType} from "./datetimepicker-filtertype"; export const MAT_DATETIMEPICKER_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -48,7 +49,6 @@ export const MAT_DATETIMEPICKER_VALIDATORS: any = { multi: true }; - /** * An event used for datepicker input and change events. We don't always have access to a native * input or change event because the event may have been triggered by the user clicking on the @@ -102,12 +102,12 @@ export class MatDatetimepickerInput implements AfterContentInit, ControlValue } } - @Input() set matDatepickerFilter(filter: (date: D | null) => boolean) { + @Input() set matDatepickerFilter(filter: (date: D | null, type: MatDatetimepickerFilterType) => boolean) { this._dateFilter = filter; this._validatorOnChange(); } - _dateFilter: (date: D | null) => boolean; + _dateFilter: (date: D | null, type: MatDatetimepickerFilterType) => boolean; /** The value of the input. */ @Input() @@ -264,7 +264,7 @@ export class MatDatetimepickerInput implements AfterContentInit, ControlValue /** The form control validator for the date filter. */ private _filterValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { const controlValue = this._dateAdapter.getValidDateOrNull(this._dateAdapter.deserialize(control.value)); - return !this._dateFilter || !controlValue || this._dateFilter(controlValue) ? + return !this._dateFilter || !controlValue || this._dateFilter(controlValue, MatDatetimepickerFilterType.DATE) ? null : {"matDatepickerFilter": true}; }; diff --git a/lib/core/src/datetimepicker/datetimepicker.ts b/lib/core/src/datetimepicker/datetimepicker.ts index 05a7af01..91a20620 100644 --- a/lib/core/src/datetimepicker/datetimepicker.ts +++ b/lib/core/src/datetimepicker/datetimepicker.ts @@ -39,6 +39,7 @@ import { DatetimeAdapter } from "../adapter/datetime-adapter"; import { MatDatetimepickerCalendar } from "./calendar"; import { createMissingDateImplError } from "./datetimepicker-errors"; import { MatDatetimepickerInput } from "./datetimepicker-input"; +import { MatDatetimepickerFilterType } from "./datetimepicker-filtertype"; /** Used to generate a unique ID for each datepicker instance. */ let datetimepickerUid = 0; @@ -209,7 +210,7 @@ export class MatDatetimepicker implements OnDestroy { return this._datepickerInput && this._datepickerInput.max; } - get _dateFilter(): (date: D | null) => boolean { + get _dateFilter(): (date: D | null, type: MatDatetimepickerFilterType) => boolean { return this._datepickerInput && this._datepickerInput._dateFilter; } diff --git a/lib/core/src/datetimepicker/index.ts b/lib/core/src/datetimepicker/index.ts index c8d26898..73f79bb5 100644 --- a/lib/core/src/datetimepicker/index.ts +++ b/lib/core/src/datetimepicker/index.ts @@ -2,6 +2,7 @@ export * from "./datetimepicker.module"; export * from "./calendar"; export * from "./calendar-body"; export * from "./datetimepicker"; +export * from "./datetimepicker-filtertype"; export * from "./datetimepicker-input"; export * from "./datetimepicker-toggle"; export * from "./month-view"; diff --git a/lib/core/src/public_api.ts b/lib/core/src/public_api.ts index 6578b311..28110bc4 100644 --- a/lib/core/src/public_api.ts +++ b/lib/core/src/public_api.ts @@ -10,6 +10,7 @@ export * from "./datetimepicker/datetimepicker.module"; export * from "./datetimepicker/calendar"; export * from "./datetimepicker/calendar-body"; export * from "./datetimepicker/datetimepicker"; +export * from "./datetimepicker/datetimepicker-filtertype"; export * from "./datetimepicker/datetimepicker-input"; export * from "./datetimepicker/datetimepicker-toggle"; export * from "./datetimepicker/month-view"; diff --git a/src/app/date.component.html b/src/app/date.component.html index bf5dc1fc..67865a30 100644 --- a/src/app/date.component.html +++ b/src/app/date.component.html @@ -31,12 +31,21 @@

Date types with: {{ type }}

required - Min Test - + Min/Max Test + required min + max + + + Filter Test + + + + required + filter TouchUi diff --git a/src/app/moment/moment.component.ts b/src/app/moment/moment.component.ts index 51bbf009..c6d8c40a 100644 --- a/src/app/moment/moment.component.ts +++ b/src/app/moment/moment.component.ts @@ -1,33 +1,28 @@ -import { Component } from "@angular/core"; -import { - FormBuilder, - FormGroup, - Validators -} from "@angular/forms"; -import { Moment } from "moment"; -import * as moment from "moment"; -import {MomentDatetimeAdapter, MAT_MOMENT_DATETIME_FORMATS} from "@mat-datetimepicker/moment"; -import {DatetimeAdapter, MAT_DATETIME_FORMATS} from "@mat-datetimepicker/core"; +import {Component} from "@angular/core"; +import {FormBuilder, FormGroup, Validators} from "@angular/forms"; +import {Moment, utc} from "moment/moment"; +import {MAT_MOMENT_DATETIME_FORMATS, MomentDatetimeAdapter} from "@mat-datetimepicker/moment"; +import {DatetimeAdapter, MatDatetimepickerFilterType, MAT_DATETIME_FORMATS} from "@mat-datetimepicker/core"; import {DateAdapter} from "@angular/material"; import {MomentDateAdapter} from "@angular/material-moment-adapter"; @Component({ selector: "app-moment-datetime", templateUrl: "../date.component.html", - providers: [ - { - provide: DateAdapter, - useClass: MomentDateAdapter - }, - { - provide: DatetimeAdapter, - useClass: MomentDatetimeAdapter - }, - { - provide: MAT_DATETIME_FORMATS, - useValue: MAT_MOMENT_DATETIME_FORMATS - } - ] + providers: [ + { + provide: DateAdapter, + useClass: MomentDateAdapter + }, + { + provide: DatetimeAdapter, + useClass: MomentDatetimeAdapter + }, + { + provide: MAT_DATETIME_FORMATS, + useValue: MAT_MOMENT_DATETIME_FORMATS + } + ] }) export class MomentDatetimeComponent { type = "moment"; @@ -36,14 +31,28 @@ export class MomentDatetimeComponent { today: Moment; tomorrow: Moment; min: Moment; + max: Moment; start: Moment; - + filter: (date: Moment, type: MatDatetimepickerFilterType) => boolean; constructor(fb: FormBuilder) { - this.today = moment().year(1929); - this.tomorrow = moment().date(moment().date() + 1); + this.today = utc().year(1929); + this.tomorrow = utc().date(utc().date() + 1); this.min = this.today.clone().year(2018).month(10).date(3).hour(11).minute(10); + this.max = this.min.clone().date(4).minute(45); this.start = this.today.clone().year(1930).month(9).date(28); + this.filter = (date: Moment, type: MatDatetimepickerFilterType) => { + switch (type) { + case MatDatetimepickerFilterType.DATE: + return date.year() % 2 === 0 && + date.month() % 2 === 0 && + date.date() % 2 === 0; + case MatDatetimepickerFilterType.HOUR: + return date.hour() % 2 === 0; + case MatDatetimepickerFilterType.MINUTE: + return date.minute() % 2 === 0; + } + }; this.group = fb.group({ dateTime: ["2017-11-09T12:10:00.000Z", Validators.required], @@ -51,6 +60,7 @@ export class MomentDatetimeComponent { time: [null, Validators.required], month: [null, Validators.required], mintest: [this.today, Validators.required], + filtertest: [this.today, Validators.required], touch: [null, Validators.required] }); } diff --git a/src/app/moment/moment.module.ts b/src/app/moment/moment.module.ts index ab312a13..a35ac74f 100644 --- a/src/app/moment/moment.module.ts +++ b/src/app/moment/moment.module.ts @@ -4,10 +4,6 @@ import { import { MatDatetimepickerModule } from "@mat-datetimepicker/core"; -import { - MatMomentDatetimeModule, - MAT_MOMENT_DATETIME_FORMATS -} from "@mat-datetimepicker/moment"; import { MomentDatetimeComponent } from "./moment.component"; import {ReactiveFormsModule} from "@angular/forms"; import {MatDatepickerModule, MatFormFieldModule, MatInputModule} from "@angular/material"; diff --git a/src/app/native/native.component.ts b/src/app/native/native.component.ts index 8959fefa..06da8b1c 100644 --- a/src/app/native/native.component.ts +++ b/src/app/native/native.component.ts @@ -4,7 +4,7 @@ import { FormGroup, Validators } from "@angular/forms"; -import {DatetimeAdapter, NativeDatetimeAdapter, MAT_DATETIME_FORMATS, MAT_NATIVE_DATETIME_FORMATS} from "@mat-datetimepicker/core"; +import {DatetimeAdapter, NativeDatetimeAdapter, MatDatetimepickerFilterType, MAT_DATETIME_FORMATS, MAT_NATIVE_DATETIME_FORMATS} from "@mat-datetimepicker/core"; import {DateAdapter, NativeDateAdapter} from "@angular/material"; @Component({ @@ -32,7 +32,9 @@ export class NativeDatetimeComponent { today = new Date(); tomorrow = new Date(); min = new Date(); + max = new Date(); start = new Date(); + filter: (date: Date, type: MatDatetimepickerFilterType) => boolean; constructor(fb: FormBuilder) { this.today.setFullYear(1929); @@ -40,8 +42,23 @@ export class NativeDatetimeComponent { this.min.setFullYear(2018, 10, 3); this.min.setHours(11); this.min.setMinutes(10); + this.max.setFullYear(2018, 10, 4); + this.max.setHours(11); + this.max.setMinutes(45); this.start.setFullYear(1930, 9, 28); - console.log(this.tomorrow); + + this.filter = (date: Date, type: MatDatetimepickerFilterType) => { + switch (type) { + case MatDatetimepickerFilterType.DATE: + return date.getUTCFullYear() % 2 === 0 && + date.getMonth() % 2 === 0 && + date.getDate() % 2 === 0; + case MatDatetimepickerFilterType.HOUR: + return date.getHours() % 2 === 0; + case MatDatetimepickerFilterType.MINUTE: + return date.getMinutes() % 2 === 0; + } + }; this.group = fb.group({ dateTime: ["2017-11-09T12:10:00.000Z", Validators.required], @@ -49,6 +66,7 @@ export class NativeDatetimeComponent { time: [null, Validators.required], month: [null, Validators.required], mintest: [this.today, Validators.required], + filtertest: [this.today, Validators.required], touch: [null, Validators.required] }); }