diff --git a/pdb-js/src/app/components/datepicker/date-picker.component.html b/pdb-js/src/app/components/datepicker/date-picker.component.html index 63c6e66..019b38f 100644 --- a/pdb-js/src/app/components/datepicker/date-picker.component.html +++ b/pdb-js/src/app/components/datepicker/date-picker.component.html @@ -38,8 +38,9 @@ (click)="isOpen = !isOpen" cdkOverlayOrigin #trigger="cdkOverlayOrigin" + [attr.disabled]="isDisabled ? 'disabled' : null" > - {{ dateValue.display }} + {{ datePickerControl.value?.display }} @@ -190,17 +191,13 @@ -
- - Date Range: - - - -
+ + Date Range: + + + + +

Value: {{ dateRange.value }}

diff --git a/pdb-js/src/app/components/datepicker/date-picker.component.ts b/pdb-js/src/app/components/datepicker/date-picker.component.ts index 9fb227a..256798a 100644 --- a/pdb-js/src/app/components/datepicker/date-picker.component.ts +++ b/pdb-js/src/app/components/datepicker/date-picker.component.ts @@ -1,15 +1,43 @@ -import { Component } from "@angular/core"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; +import { + Component, + EventEmitter, + forwardRef, + Input, + Output, +} from "@angular/core"; +import { + ControlValueAccessor, + FormControl, + NG_VALUE_ACCESSOR, + Validators, +} from "@angular/forms"; export type DateType = "quick" | "relative" | "absolute"; -export type DateValue = { type: DateType; value: string; display: string }; +export class DateValue { + constructor( + public type: DateType, + public value: string, + public display: string, + ) {} +} + +export class DatePickerChange { + constructor(public value: DateValue) {} +} @Component({ selector: "app-date-picker", templateUrl: "./date-picker.component.html", + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DatePickerComponent), + multi: true, + }, + ], }) -export class DatePickerComponent { +export class DatePickerComponent implements ControlValueAccessor { isOpen = false; relativeTimeRangeUnit = "relativeTimeRangeMinutes"; @@ -25,39 +53,88 @@ export class DatePickerComponent { years: 0, }; - dateRangeFormGroup = new FormGroup({ - dateRange: new FormControl( - "2019-10-05 00:00:00 - 2019-10-11 23:59:59", - [ - Validators.pattern( - /^\d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2} - \d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2}$/, - ), - ], - ), - }); + dateRange = new FormControl( + "2019-10-05 00:00:00 - 2019-10-11 23:59:59", + [ + Validators.pattern( + /^\d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2} - \d{4}-\d{2}-\d{2} ([01][0-9]|2[0-3]):\d{2}:\d{2}$/, + ), + ], + ); - dateValue: DateValue = { - type: "quick", - value: "BM/EM", - display: "this month", - }; + datePickerControl = new FormControl( + new DateValue("quick", "BE/EM", "this month"), + ); + + @Input() + isDisabled: boolean = false; + + @Output() + readonly dateValueSelected: EventEmitter = new EventEmitter< + DatePickerChange + >(); selectedTabIndex = 0; + _onChange = (_: any) => {}; + + _onTouched = (_: any) => {}; + constructor() {} + writeValue(obj: DateValue): void { + this.datePickerControl.setValue(obj); + switch (obj.type) { + case "quick": + break; + case "absolute": + this.dateRange.setValue(obj.value); + break; + case "relative": + const x = this.relativeTimeRange; + // obj.value looks like "P1Y2M3DT4H5M6S" or "PT4H5M6S" or "P1Y2M3D" or "P1YT6S" or ... + const matches = obj.value.match( + /P(?:(\d+)Y)(?:(\d+)M)(?:(\d+)D)?(?:T(?:(\d+)H)(?:(\d+)M)(?:(\d+)S))?/, + ) ?? []; + + x.years = Number.parseInt(matches[1] ?? 0); + x.months = Number.parseInt(matches[2] ?? 0); + x.days = Number.parseInt(matches[3] ?? 0); + x.hours = Number.parseInt(matches[4] ?? 0); + x.minutes = Number.parseInt(matches[5] ?? 0); + x.seconds = Number.parseInt(matches[6] ?? 0); + break; + default: + } + } + registerOnChange(fn: any): void { + this._onChange = fn; + } + registerOnTouched(fn: any): void { + this._onTouched = fn; + } + setDisabledState?(isDisabled: boolean): void { + this.isDisabled = isDisabled; + } + dateDisplay(): string { - return this.dateValue.value; + return this.datePickerControl.value?.display || "no date set"; } tabChange() { //( window).initSimpleDatePicker(); // breaks form control } + _setDateValue(dateValue: DateValue) { + this.datePickerControl.setValue(dateValue); + this._onChange(dateValue); + this.dateValueSelected.emit(new DatePickerChange(dateValue)); + //console.log("date value updated: ", dateValue); + } + applyQuick(value: string, display: string) { - this.dateValue.type = "quick"; - this.dateValue.value = value; - this.dateValue.display = display; + const newValue = new DateValue("quick", value, display); + this._setDateValue(newValue); this.isOpen = false; } @@ -77,20 +154,16 @@ export class DatePickerComponent { const isoTimeRange = `P${years}${months}${days}${time}${hours}${minutes}${seconds}`; - this.dateValue.type = "relative"; - this.dateValue.value = isoTimeRange; - this.dateValue.display = isoTimeRange; + const newValue = new DateValue("relative", isoTimeRange, isoTimeRange); + this._setDateValue(newValue); this.isOpen = false; } applyAbsoluteTime() { - this.dateValue.type = "absolute"; - this.dateValue.value = this.dateRangeFormGroup.controls.dateRange - .value; - this.dateValue.display = this.dateRangeFormGroup.controls.dateRange - .value; + const value = this.dateRange.value; + const newValue = new DateValue("absolute", value, value); + this._setDateValue(newValue); this.isOpen = false; - console.log(this.dateValue); } scrollRelativeTimeRange(