src/app/core/basic-datatypes/date-with-age/edit-age/edit-age.component.ts
CustomFormControlDirective<DateWithAge>
| changeDetection | ChangeDetectionStrategy.OnPush |
| providers |
EditAgeComponent
|
| selector | app-edit-age |
| standalone | true |
| imports |
MatInputModule
MatDatepickerModule
FontAwesomeModule
MatTooltipModule
|
| styleUrls | ../../../entity/entity-field-edit/dynamic-edit/dynamic-edit.component.scss, |
| templateUrl | ./edit-age.component.html |
No results matching.
ReactiveFormsModule
MatInputModule
MatDatepickerModule
FontAwesomeModule
MatTooltipModule
CustomFormControlDirective<DateWithAge>
EditComponent
OnInit
Properties |
|
Methods |
Inputs |
Outputs |
| entity | |
Type : Entity
|
|
| formFieldConfig | |
Type : FormFieldConfig
|
|
| aria-describedby | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| disabled | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| ngControl | |
Type : any
|
|
Default value : inject(NgControl, { optional: true, self: true })
|
|
|
Inherited from
CustomFormControlDirective
|
|
| placeholder | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| required | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| value | |
Type : T
|
|
|
Inherited from
CustomFormControlDirective
|
|
| valueChange | |
Type : EventEmitter
|
|
|
Inherited from
CustomFormControlDirective
|
|
| writeValue | ||||||
writeValue(newValue: DateWithAge | Date)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| blur |
blur()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| focus |
focus()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| onContainerClick | ||||||
onContainerClick(event: MouseEvent)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnChange | ||||||
registerOnChange(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnTouched | ||||||
registerOnTouched(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDescribedByIds | ||||||
setDescribedByIds(ids: string[])
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| Readonly age |
Type : unknown
|
Default value : computed(() => this.valueSignal()?.age ?? null)
|
|
The age derived from the current date value, kept reactive via the base |
| controlType |
Type : string
|
Default value : "custom-control"
|
|
Inherited from
CustomFormControlDirective
|
| elementRef |
Type : unknown
|
Default value : inject<ElementRef<HTMLElement>>(ElementRef)
|
|
Inherited from
CustomFormControlDirective
|
| Readonly enabled |
Type : Signal<boolean>
|
Default value : computed(() => !this._disabled())
|
|
Inherited from
CustomFormControlDirective
|
|
Whether the control is currently enabled, as a signal (tracks disabled). |
| errorStateMatcher |
Type : unknown
|
Default value : inject(ErrorStateMatcher)
|
|
Inherited from
CustomFormControlDirective
|
| id |
Type : unknown
|
Default value : `custom-form-control-${CustomFormControlDirective.nextId++}`
|
|
Inherited from
CustomFormControlDirective
|
| Static nextId |
Type : number
|
Default value : 0
|
|
Inherited from
CustomFormControlDirective
|
| onChange |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| onTouched |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| parentForm |
Type : unknown
|
Default value : inject(NgForm, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| parentFormGroup |
Type : unknown
|
Default value : inject(FormGroupDirective, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| stateChanges |
Type : unknown
|
Default value : new Subject<void>()
|
|
Inherited from
CustomFormControlDirective
|
| Readonly valueSignal |
Type : Signal<T>
|
Default value : computed(() => this._value())
|
|
Inherited from
CustomFormControlDirective
|
|
The current value of the control as a signal.
Authoritative in both modes: it reflects the bound |
import { Entity } from "#src/app/core/entity/model/entity";
import {
Component,
computed,
input,
OnInit,
ChangeDetectionStrategy,
} from "@angular/core";
import { ReactiveFormsModule } from "@angular/forms";
import { MatDatepickerModule } from "@angular/material/datepicker";
import { MatFormFieldControl } from "@angular/material/form-field";
import { MatInputModule } from "@angular/material/input";
import { MatTooltipModule } from "@angular/material/tooltip";
import { FontAwesomeModule } from "@fortawesome/angular-fontawesome";
import { CustomFormControlDirective } from "../../../common-components/basic-autocomplete/custom-form-control.directive";
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 { DateWithAge } from "../dateWithAge";
@DynamicComponent("EditAge")
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-edit-age",
templateUrl: "./edit-age.component.html",
styleUrls: [
"../../../entity/entity-field-edit/dynamic-edit/dynamic-edit.component.scss",
"./edit-age.component.scss",
],
imports: [
ReactiveFormsModule,
MatInputModule,
MatDatepickerModule,
FontAwesomeModule,
MatTooltipModule,
],
providers: [{ provide: MatFormFieldControl, useExisting: EditAgeComponent }],
})
export class EditAgeComponent
extends CustomFormControlDirective<DateWithAge>
implements EditComponent, OnInit
{
formFieldConfig = input<FormFieldConfig>();
entity = input<Entity>();
/** The age derived from the current date value, kept reactive via the base `valueSignal`. */
readonly age = computed(() => this.valueSignal()?.age ?? null);
override writeValue(newValue: DateWithAge | Date) {
if (newValue instanceof Date && !(newValue instanceof DateWithAge)) {
super.writeValue(new DateWithAge(newValue));
} else {
super.writeValue(newValue);
}
}
ngOnInit() {
// Ensure the stored value is always a DateWithAge (so `.age` is available).
// In EditComponent mode the value flows through the control, not writeValue.
this.formControl.valueChanges.subscribe((newValue) => {
if (newValue instanceof Date && !(newValue instanceof DateWithAge)) {
this.formControl.setValue(new DateWithAge(newValue));
}
});
}
}
<div class="flex-row align-center gap-small">
@if (
!(
entity()?.anonymized &&
formFieldConfig()?.anonymize === "retain-anonymized"
)
) {
<input
matInput
[formControl]="formControl"
[matDatepicker]="dateOfBirthDatepicker"
class="flex-grow"
/>
<mat-datepicker-toggle
[for]="dateOfBirthDatepicker"
class="input-action-button"
></mat-datepicker-toggle>
<mat-datepicker #dateOfBirthDatepicker></mat-datepicker>
}
<div class="flex-row align-center gap-small age-display-container">
<span class="age-label" i18n="Label for the age display">Age:</span>
<span>{{ age() || "-" }}</span>
<fa-icon
icon="question-circle"
i18n-matTooltip="Tooltip for the disabled age field"
matTooltip="This field is read-only. Edit the date field to update the age. You can select Jan 1st if you don't know the exact date."
class="age-help-icon"
[class.visible]="enabled()"
[class.hidden]="!enabled()"
></fa-icon>
</div>
</div>
../../../entity/entity-field-edit/dynamic-edit/dynamic-edit.component.scss
.input-action-button {
margin: -12px;
}
./edit-age.component.scss
@use "variables/colors";
.age-display-container {
margin-left: 8px;
margin-top: -8px;
padding: 4px 8px;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.12);
}
input[matInput] {
min-width: 6.5rem;
}
.age-label {
font-size: 12px;
color: rgba(0, 0, 0, 0.6);
font-weight: 500;
}
.age-help-icon {
color: rgba(0, 0, 0, 0.6);
cursor: help;
&.hidden {
display: none;
}
&.visible {
visibility: visible;
}
}