From 84255497c4ae78a3f539ead44d797f7d50715405 Mon Sep 17 00:00:00 2001 From: jmarkowski Date: Mon, 17 Jun 2019 22:54:15 +0200 Subject: [PATCH] fix: add custom formatting to datetime picker (#918) * add custom formatting to datetime picker * Change time delimiters --- .../datetime-picker-docs.component.html | 9 ++++ .../datetime-picker-docs.component.ts | 6 +++ .../datetime-format-example.component.html | 3 ++ .../datetime-format-example.component.ts | 37 ++++++++++++++ .../app/documentation/documentation.module.ts | 2 + .../datetime-picker.component.ts | 13 +++-- .../datetime-picker/format/datetime-parser.ts | 50 +++++++++++++++++++ 7 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.html create mode 100644 docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.ts create mode 100644 library/src/lib/datetime-picker/format/datetime-parser.ts diff --git a/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.html b/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.html index c42cd4c89be..971d46873ec 100644 --- a/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.html +++ b/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.html @@ -39,3 +39,12 @@

Null Validity

+ + +

Formatting

+Providing a custom format for the dates is possible through providing a service. + + + + + diff --git a/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.ts b/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.ts index 2345e31a68e..3b4723c95a3 100644 --- a/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.ts +++ b/docs/app/documentation/component-docs/datetime-picker/datetime-picker-docs.component.ts @@ -11,6 +11,9 @@ import * as dateTimeProgTs from '!raw-loader!./examples/datetime-program-example import * as dateTimePickerAllowNullTs from '!raw-loader!./examples/datetime-allow-null-example/datetime-allow-null-example.component.ts'; +import * as dateTimeFormatHtml from '!raw-loader!./examples/datetime-format-example/datetime-format-example.component.html'; +import * as dateTimeFormatTs from '!raw-loader!./examples/datetime-format-example/datetime-format-example.component.ts'; + @Component({ selector: 'app-datetime-picker-docs', @@ -28,6 +31,9 @@ export class DatetimePickerDocsComponent { datetimeProgramHtml = dateTimeProgHtml; datetimeProgramTs = dateTimeProgTs; + datetimeFormatHtml = dateTimeFormatHtml; + datetimeFormatTs = dateTimeFormatTs; + datetimePickerAllowNullTs = dateTimePickerAllowNullTs; } diff --git a/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.html b/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.html new file mode 100644 index 00000000000..68a91693df1 --- /dev/null +++ b/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.html @@ -0,0 +1,3 @@ + +

+Selected: {{date ? date.toLocaleString() : 'null'}} diff --git a/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.ts b/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.ts new file mode 100644 index 00000000000..38a3f9e880d --- /dev/null +++ b/docs/app/documentation/component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component.ts @@ -0,0 +1,37 @@ +import { Component, Injectable } from '@angular/core'; +import { DateTimeFormatParser } from '../../../../../../../library/src/lib/datetime-picker/format/datetime-parser'; + +@Injectable() +export class DateTimeFormatExample extends DateTimeFormatParser { + + public parse(value: string): Date { + value = value.replace(/[\/hms ]/g, '-'); + const values: number[] = value.split('-').map(Number); + return new Date(Number(values[1] - 1), values[0], values[2], values[3], values[4], values[5]); + } + + public format(date: Date): string { + const getAtLeastTwoDigits = function(num: number): string { return num < 10 ? '0' + num : String(num) }; + return date.getFullYear() + '-' + + getAtLeastTwoDigits(date.getMonth() + 1) + '-' + + date.getDate() + ' ' + + getAtLeastTwoDigits(date.getHours()) + 'h' + + getAtLeastTwoDigits(date.getMinutes()) + 'm' + + getAtLeastTwoDigits(date.getSeconds()) + 's' + } +} + + +@Component({ + selector: 'fd-datetime-format-example', + templateUrl: './datetime-format-example.component.html', + providers: [ + { + provide: DateTimeFormatParser, + useClass: DateTimeFormatExample + } + ] +}) +export class DatetimeFormatExampleComponent { + date = new Date(); +} diff --git a/docs/app/documentation/documentation.module.ts b/docs/app/documentation/documentation.module.ts index eec523d1380..a81e02b1448 100644 --- a/docs/app/documentation/documentation.module.ts +++ b/docs/app/documentation/documentation.module.ts @@ -320,6 +320,7 @@ import { DatetimePickerAllowNullExampleComponent } from './component-docs/dateti import { DatePickerAllowNullExampleComponent } from './component-docs/date-picker/examples/date-picker-allow-null-example.component'; import { TimeFormExampleComponent } from './component-docs/time/examples/time-form-example.component'; import { TableResponsiveExampleComponent } from './component-docs/table/examples/table-responsive-example.component'; +import { DatetimeFormatExampleComponent } from './component-docs/datetime-picker/examples/datetime-format-example/datetime-format-example.component'; @@ -410,6 +411,7 @@ export function highlightJsFactory() { DatetimeExampleComponent, DatetimeNonMeridianExampleComponent, DatetimeProgramExampleComponent, + DatetimeFormatExampleComponent, DatetimePickerAllowNullExampleComponent, DropdownContextualMenuExampleComponent, DropdownDefaultExampleComponent, diff --git a/library/src/lib/datetime-picker/datetime-picker.component.ts b/library/src/lib/datetime-picker/datetime-picker.component.ts index 81b22c89b41..7c438627537 100644 --- a/library/src/lib/datetime-picker/datetime-picker.component.ts +++ b/library/src/lib/datetime-picker/datetime-picker.component.ts @@ -16,6 +16,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subject, Subscription } from 'rxjs'; import { TimeObject } from '../time/time-object'; import { TimeComponent } from '../time/time.component'; +import { DateTimeFormatParser } from './format/datetime-parser'; /** * The datetime picker component is an opinionated composition of the fd-popover, @@ -204,7 +205,7 @@ export class DatetimePickerComponent implements OnInit, OnDestroy, ControlValueA const previous = this.date.getTime(); this.selectedDay = d.selectedDay; this.date = d.selectedDay.date; - this.inputFieldDate = this.date.toLocaleString(); + this.inputFieldDate = this.dateTimeAdapter.format(this.date); this.time = {hour: this.date.getHours(), minute: this.date.getMinutes(), second: this.date.getSeconds()}; if (this.date.getTime() !== previous) { this.calendarChange.emit(this.date); @@ -236,7 +237,7 @@ export class DatetimePickerComponent implements OnInit, OnDestroy, ControlValueA inputValueChange(e): void { let temp; if (typeof e === 'string') { - temp = new Date(e.replace(/-/g, '/')); + temp = this.dateTimeAdapter.parse(e); } else { temp = new Date(e); } @@ -251,7 +252,7 @@ export class DatetimePickerComponent implements OnInit, OnDestroy, ControlValueA meridianValid = false; } - if (meridianValid && temp.toLocaleDateString() !== 'Invalid Date') { + if (meridianValid && temp && temp.toLocaleDateString() !== 'Invalid Date') { const newValue = {hour: temp.getHours(), minute: temp.getMinutes(), second: temp.getSeconds()}; if (newValue.hour !== this.time.hour || newValue.minute !== this.time.minute || newValue.second !== this.time.second) { this.time = newValue; @@ -301,7 +302,9 @@ export class DatetimePickerComponent implements OnInit, OnDestroy, ControlValueA } /** @hidden */ - constructor(private elRef: ElementRef) {} + constructor(private elRef: ElementRef, + private dateTimeAdapter: DateTimeFormatParser + ) {} /** @hidden */ registerOnChange(fn: (selected: any) => {void}): void { @@ -334,7 +337,7 @@ export class DatetimePickerComponent implements OnInit, OnDestroy, ControlValueA this.date.setHours(this.time.hour); this.date.setMinutes(this.time.minute); this.date.setSeconds(this.time.second); - this.inputFieldDate = this.date.toLocaleString(); + this.inputFieldDate = this.dateTimeAdapter.format(this.date); if (fireEvents) { this.timeChange.emit(this.date); diff --git a/library/src/lib/datetime-picker/format/datetime-parser.ts b/library/src/lib/datetime-picker/format/datetime-parser.ts new file mode 100644 index 00000000000..fb4890a4098 --- /dev/null +++ b/library/src/lib/datetime-picker/format/datetime-parser.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@angular/core'; + +export function DATE_TIME_FORMAT_FACTORY() { + return new DateTimeFormatParserDefault(); +} + +/** + * Abstract class which defines the behaviour of the datetime format and parser. + */ +@Injectable({ + providedIn: 'root', + useFactory: DATE_TIME_FORMAT_FACTORY +}) +export abstract class DateTimeFormatParser { + + /** + * Should take in a string value and return a date object. + * @param value String to concert to a date object. + */ + abstract parse(value: string): Date; + + /** + * Should take in a date object and return a string representation. + * @param date String to concert to a date object. + */ + abstract format(date: Date): string; +} + +/** + * Default implementation of the DateFormatParser service. + */ +@Injectable() +export class DateTimeFormatParserDefault extends DateTimeFormatParser { + + /** + * Takes in a string representation of a date and returns a Date object. + * @param value String to convert to a date. + */ + public parse(value: string): Date { + return new Date(value); + } + + /** + * Takes in a date object and returns the string representation. + * @param date Date object to convert to a string. + */ + public format(date: Date): string { + return date.toLocaleString(); + } +}