add date picker component

This commit is contained in:
2024-04-25 09:41:10 +02:00
parent 380bad6967
commit 6d6b6ba00c
2 changed files with 114 additions and 44 deletions

View File

@@ -38,8 +38,9 @@
(click)="isOpen = !isOpen" (click)="isOpen = !isOpen"
cdkOverlayOrigin cdkOverlayOrigin
#trigger="cdkOverlayOrigin" #trigger="cdkOverlayOrigin"
[attr.disabled]="isDisabled ? 'disabled' : null"
> >
{{ dateValue.display }} {{ datePickerControl.value?.display }}
</button> </button>
</div> </div>
@@ -190,17 +191,13 @@
<button mat-button (click)="applyRelativeTimeRange()">Apply</button> <button mat-button (click)="applyRelativeTimeRange()">Apply</button>
</mat-tab> </mat-tab>
<mat-tab label="Absolute"> <mat-tab label="Absolute">
<form [formGroup]="dateRangeFormGroup"> <mat-form-field class="date-picker-form-field">
<mat-form-field class="date-picker-form-field"> <mat-label>Date Range:</mat-label>
<mat-label>Date Range:</mat-label> <input matInput [formControl]="dateRange" name="dates" />
<input </mat-form-field>
matInput <button mat-button (click)="applyAbsoluteTime()">Apply</button>
[formControl]="dateRangeFormGroup.controls.dateRange"
name="dates" <p>Value: {{ dateRange.value }}</p>
/>
</mat-form-field>
<button mat-button (click)="applyAbsoluteTime()">Apply</button>
</form>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>

View File

@@ -1,15 +1,43 @@
import { Component } from "@angular/core"; import {
import { FormControl, FormGroup, Validators } from "@angular/forms"; 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 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({ @Component({
selector: "app-date-picker", selector: "app-date-picker",
templateUrl: "./date-picker.component.html", 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; isOpen = false;
relativeTimeRangeUnit = "relativeTimeRangeMinutes"; relativeTimeRangeUnit = "relativeTimeRangeMinutes";
@@ -25,39 +53,88 @@ export class DatePickerComponent {
years: 0, years: 0,
}; };
dateRangeFormGroup = new FormGroup({ dateRange = new FormControl<string>(
dateRange: new FormControl<string>( "2019-10-05 00:00:00 - 2019-10-11 23:59:59",
"2019-10-05 00:00:00 - 2019-10-11 23:59:59", [
[ Validators.pattern(
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}$/,
/^\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 = { datePickerControl = new FormControl(
type: "quick", new DateValue("quick", "BE/EM", "this month"),
value: "BM/EM", );
display: "this month",
}; @Input()
isDisabled: boolean = false;
@Output()
readonly dateValueSelected: EventEmitter<DatePickerChange> = new EventEmitter<
DatePickerChange
>();
selectedTabIndex = 0; selectedTabIndex = 0;
_onChange = (_: any) => {};
_onTouched = (_: any) => {};
constructor() {} 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 { dateDisplay(): string {
return this.dateValue.value; return this.datePickerControl.value?.display || "no date set";
} }
tabChange() { tabChange() {
//(<any> window).initSimpleDatePicker(); // breaks form control //(<any> 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) { applyQuick(value: string, display: string) {
this.dateValue.type = "quick"; const newValue = new DateValue("quick", value, display);
this.dateValue.value = value; this._setDateValue(newValue);
this.dateValue.display = display;
this.isOpen = false; this.isOpen = false;
} }
@@ -77,20 +154,16 @@ export class DatePickerComponent {
const isoTimeRange = const isoTimeRange =
`P${years}${months}${days}${time}${hours}${minutes}${seconds}`; `P${years}${months}${days}${time}${hours}${minutes}${seconds}`;
this.dateValue.type = "relative"; const newValue = new DateValue("relative", isoTimeRange, isoTimeRange);
this.dateValue.value = isoTimeRange; this._setDateValue(newValue);
this.dateValue.display = isoTimeRange;
this.isOpen = false; this.isOpen = false;
} }
applyAbsoluteTime() { applyAbsoluteTime() {
this.dateValue.type = "absolute"; const value = <string> this.dateRange.value;
this.dateValue.value = <string> this.dateRangeFormGroup.controls.dateRange const newValue = new DateValue("absolute", value, value);
.value; this._setDateValue(newValue);
this.dateValue.display = <string> this.dateRangeFormGroup.controls.dateRange
.value;
this.isOpen = false; this.isOpen = false;
console.log(this.dateValue);
} }
scrollRelativeTimeRange( scrollRelativeTimeRange(