src/app/core/basic-datatypes/date/edit-date-format/edit-date-format.component.ts

Description

Edit component for date format configuration. Provides predefined format options and allows custom format strings.

Extends

CustomFormControlDirective<string>

Implements

EditComponent OnInit

Example

Metadata

Relationships

Index

Properties
Methods
Inputs
Outputs

Inputs

formFieldConfig
Type : FormFieldConfig
aria-describedby
Type : string
disabled
Type : boolean
ngControl
Type : any
Default value : inject(NgControl, { optional: true, self: true })
placeholder
Type : string
required
Type : boolean
value
Type : T

Outputs

valueChange
Type : EventEmitter

Methods

blur
blur()
Returns : void
focus
focus()
Returns : void
onContainerClick
onContainerClick(event: MouseEvent)
Parameters :
Name Type Optional
event MouseEvent No
Returns : void
registerOnChange
registerOnChange(fn: any)
Parameters :
Name Type Optional
fn any No
Returns : void
registerOnTouched
registerOnTouched(fn: any)
Parameters :
Name Type Optional
fn any No
Returns : void
setDescribedByIds
setDescribedByIds(ids: string[])
Parameters :
Name Type Optional
ids string[] No
Returns : void
setDisabledState
setDisabledState(isDisabled: boolean)
Parameters :
Name Type Optional
isDisabled boolean No
Returns : void
writeValue
writeValue(value: T, notifyFormControl: unknown)

Implementation for Angular ControlValueAccessor interface that links the form control value to the component value

Parameters :
Name Type Optional Default value Description
value T No

The new value to set

notifyFormControl unknown No false

Whether to notify the FormControl of this change (for internal updates)

Returns : void

Properties

createCustomFormat
Type : unknown
Default value : () => {...}
formatOptions
Type : Signal<string[]>
Default value : computed(() => { const value = this.currentValue(); if (value && !this.predefinedFormats.includes(value)) { return [...this.predefinedFormats, value]; } return this.predefinedFormats; })

Get all format options including any custom format currently set

formatOptionToString
Type : unknown
Default value : () => {...}
Readonly predefinedFormats
Type : string[]
Default value : [ "dd.MM.yyyy", "MM/dd/yyyy", "yyyy-MM-dd", "dd/MM/yyyy", "MMM d, yyyy", ]
controlType
Type : string
Default value : "custom-control"
elementRef
Type : unknown
Default value : inject<ElementRef<HTMLElement>>(ElementRef)
Readonly enabled
Type : Signal<boolean>
Default value : computed(() => !this._disabled())

Whether the control is currently enabled, as a signal (tracks disabled).

errorStateMatcher
Type : unknown
Default value : inject(ErrorStateMatcher)
id
Type : unknown
Default value : `custom-form-control-${CustomFormControlDirective.nextId++}`
Static nextId
Type : number
Default value : 0
onChange
Type : unknown
Default value : () => {...}
onTouched
Type : unknown
Default value : () => {...}
parentForm
Type : unknown
Default value : inject(NgForm, { optional: true })
parentFormGroup
Type : unknown
Default value : inject(FormGroupDirective, { optional: true })
stateChanges
Type : unknown
Default value : new Subject<void>()
Readonly valueSignal
Type : Signal<T>
Default value : computed(() => this._value())

The current value of the control as a signal. Authoritative in both modes: it reflects the bound FormControl (synced in ngDoCheck) as well as [(value)] / writeValue updates.

import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
  input,
  LOCALE_ID,
  OnInit,
  Signal,
  signal,
  WritableSignal,
} from "@angular/core";
import { DatePipe } from "@angular/common";
import { ReactiveFormsModule } from "@angular/forms";
import { MatFormFieldControl } from "@angular/material/form-field";
import { FormFieldConfig } from "../../../common-components/entity-form/FormConfig";
import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator";
import { EditComponent } from "../../../entity/entity-field-edit/dynamic-edit/edit-component.interface";
import { CustomFormControlDirective } from "../../../common-components/basic-autocomplete/custom-form-control.directive";
import { BasicAutocompleteComponent } from "../../../common-components/basic-autocomplete/basic-autocomplete.component";

/**
 * Edit component for date format configuration.
 * Provides predefined format options and allows custom format strings.
 */
@DynamicComponent("EditDateFormat")
@Component({
  selector: "app-edit-date-format",
  templateUrl: "./edit-date-format.component.html",
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [BasicAutocompleteComponent, ReactiveFormsModule],
  providers: [
    { provide: MatFormFieldControl, useExisting: EditDateFormatComponent },
  ],
})
export class EditDateFormatComponent
  extends CustomFormControlDirective<string>
  implements EditComponent, OnInit
{
  formFieldConfig = input<FormFieldConfig>();

  private readonly datePipe = new DatePipe(inject(LOCALE_ID));
  // Fixed reference date to illustrate each format: January 22, 2026
  private readonly exampleDate = new Date(2026, 0, 22);

  readonly predefinedFormats: string[] = [
    "dd.MM.yyyy",
    "MM/dd/yyyy",
    "yyyy-MM-dd",
    "dd/MM/yyyy",
    "MMM d, yyyy",
  ];

  formatOptionToString = (format: string): string => {
    try {
      const example = this.datePipe.transform(this.exampleDate, format) ?? "";
      // Angular DatePipe interprets unknown characters as tokens and never throws,
      // so we verify the output actually contains the example year as a sanity check.
      const exampleYear = this.datePipe.transform(this.exampleDate, "y");
      return example?.includes(exampleYear)
        ? `${format}  (${example})`
        : format;
    } catch {
      return format;
    }
  };

  private readonly currentValue: WritableSignal<string | null | undefined> =
    signal(undefined);

  ngOnInit() {
    this.currentValue.set(this.formControl.value);
    this.formControl.valueChanges.subscribe((value) => {
      this.currentValue.set(value);
    });
  }

  /**
   * Get all format options including any custom format currently set
   */
  formatOptions: Signal<string[]> = computed(() => {
    const value = this.currentValue();
    if (value && !this.predefinedFormats.includes(value)) {
      return [...this.predefinedFormats, value];
    }
    return this.predefinedFormats;
  });

  createCustomFormat = async (input: string) => input.trim();
}
<app-basic-autocomplete
  [formControl]="formControl"
  [options]="formatOptions()"
  [optionToString]="formatOptionToString"
  [createOption]="createCustomFormat"
></app-basic-autocomplete>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""