diff --git a/lib/core/src/lib/form/components/widgets/amount/amount.widget.html b/lib/core/src/lib/form/components/widgets/amount/amount.widget.html index 6727eb3d12..a94613e563 100644 --- a/lib/core/src/lib/form/components/widgets/amount/amount.widget.html +++ b/lib/core/src/lib/form/components/widgets/amount/amount.widget.html @@ -10,7 +10,7 @@ >
- + @if ( (field.name || field?.required) && !field.leftLabels) { {{field.name | translate }} } @if(!enableDisplayBasedOnLocale) { {{ currency }}  @@ -27,16 +27,16 @@ [(ngModel)]="amountWidgetValue" (ngModelChange)="onFieldChangedAmountWidget()" [disabled]="field.readOnly" + [errorStateMatcher]="errorStateMatcher" (focus)="amountWidgetOnFocus()" (blur)="amountWidgetOnBlur()" /> + + {{ field.validationSummary.message | translate:translateParameters }} + + + {{ 'FORM.FIELD.REQUIRED' | translate }} + -
- - -
diff --git a/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts b/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts index 3ba65caae7..9d952ab42a 100644 --- a/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts +++ b/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts @@ -19,11 +19,11 @@ import { CurrencyPipe, NgIf } from '@angular/common'; import { Component, OnInit, ViewEncapsulation, InjectionToken, inject, DestroyRef } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, FormGroupDirective, NgForm, UntypedFormControl } from '@angular/forms'; +import { ErrorStateMatcher } from '@angular/material/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; -import { ErrorWidgetComponent } from '../error/error.component'; import { WidgetComponent } from '../widget.component'; import { filter, isObservable, Observable } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -52,7 +52,7 @@ export const ADF_AMOUNT_SETTINGS = new InjectionToken = {}; valueAsNumber: number; get placeholder(): string { @@ -117,6 +119,23 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit { } this.subscribeToFieldChanges(); this.setInitialValues(); + this.initErrorStateMatcher(); + this.updateTranslateParameters(); + } + } + + private initErrorStateMatcher(): void { + this.errorStateMatcher = { + isErrorState: (_control: UntypedFormControl | null, _form: FormGroupDirective | NgForm | null): boolean => + !this.field.isValid && this.isTouched() + }; + } + + private updateTranslateParameters(): void { + if (this.field.validationSummary?.isActive()) { + this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); + } else { + this.translateParameters = {}; } } @@ -138,6 +157,7 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit { } } this.markAsTouched(); + this.updateTranslateParameters(); } amountWidgetOnFocus(): void { @@ -156,6 +176,8 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit { onFieldChangedAmountWidget(): void { this.field.value = this.amountWidgetValue; super.onFieldChanged(this.field); + this.markAsTouched(); + this.updateTranslateParameters(); } setInitialValues(): void { @@ -180,6 +202,7 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit { } else if (!this.isInputInFocus) { this.amountWidgetValue = ev.field.value; } + this.updateTranslateParameters(); }); } diff --git a/lib/core/src/lib/form/components/widgets/text/text.widget.html b/lib/core/src/lib/form/components/widgets/text/text.widget.html index 13e1c165ef..b580f79e29 100644 --- a/lib/core/src/lib/form/components/widgets/text/text.widget.html +++ b/lib/core/src/lib/form/components/widgets/text/text.widget.html @@ -8,7 +8,7 @@
- + @if ( (field.name || this.field?.required) && !field.leftLabels) { {{ field.name | translate }} @@ -20,20 +20,24 @@ [required]="field.required" [value]="field.value" [(ngModel)]="field.value" - (ngModelChange)="onFieldChanged(field)" + (ngModelChange)="onTextFieldChanged()" [disabled]="field.readOnly || readOnly" [textMask]="{mask: mask, isReversed: isMaskReversed}" [placeholder]="placeholder" [title]="field.tooltip" - (blur)="markAsTouched()"> + [errorStateMatcher]="errorStateMatcher" + (blur)="onBlur()"> + @if (field.validationSummary?.message) { + + {{ field.validationSummary.message | translate:translateParameters }} + + } + @if (isInvalidFieldRequired() && isTouched()) { + + {{ 'FORM.FIELD.REQUIRED' | translate }} + + } - - -
- - -
-
+
diff --git a/lib/core/src/lib/form/components/widgets/text/text.widget.ts b/lib/core/src/lib/form/components/widgets/text/text.widget.ts index ef6ddbb515..2fb04700a7 100644 --- a/lib/core/src/lib/form/components/widgets/text/text.widget.ts +++ b/lib/core/src/lib/form/components/widgets/text/text.widget.ts @@ -20,15 +20,16 @@ import { NgIf, NgTemplateOutlet } from '@angular/common'; import { Component, DestroyRef, Directive, inject, InjectionToken, Input, OnInit, TemplateRef, ViewEncapsulation } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, FormGroupDirective, NgForm, UntypedFormControl } from '@angular/forms'; +import { ErrorStateMatcher } from '@angular/material/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { TranslatePipe } from '@ngx-translate/core'; import { isObservable } from 'rxjs'; import { ADF_CUSTOM_MESSAGE } from '../core/custom-validation-message.token'; -import { ErrorWidgetComponent } from '../error/error.component'; import { WidgetComponent } from '../widget.component'; import { InputMaskDirective } from './text-mask.component'; +import { IconModule } from '../../../../icon/icon.module'; type FieldStatusTemplate = TemplateRef<{ $implicit: WidgetComponent }>; const FIELD_STATUS_TEMPLATE = new InjectionToken('FIELD_STATUS_TEMPLATE'); @@ -63,7 +64,7 @@ export class FieldStatusTemplateDirective { '(invalid)': 'event($event)', '(select)': 'event($event)' }, - imports: [NgIf, TranslatePipe, MatFormFieldModule, MatInputModule, FormsModule, ErrorWidgetComponent, InputMaskDirective, NgTemplateOutlet], + imports: [NgIf, TranslatePipe, MatFormFieldModule, MatInputModule, FormsModule, InputMaskDirective, NgTemplateOutlet, IconModule], encapsulation: ViewEncapsulation.None }) export class TextWidgetComponent extends WidgetComponent implements OnInit { @@ -71,6 +72,8 @@ export class TextWidgetComponent extends WidgetComponent implements OnInit { placeholder: string; isMaskReversed: boolean; fieldStatusTemplate = inject(FIELD_STATUS_TEMPLATE, { optional: true }); + errorStateMatcher: ErrorStateMatcher; + translateParameters: Record = {}; private readonly destroyRef = inject(DestroyRef); private readonly enableCustomMessage = inject(ADF_CUSTOM_MESSAGE, { optional: true }); @@ -98,5 +101,31 @@ export class TextWidgetComponent extends WidgetComponent implements OnInit { : this.field.placeholder; this.isMaskReversed = this.field.params['inputMaskReversed'] ? this.field.params['inputMaskReversed'] : false; } + this.initErrorStateMatcher(); + } + + private initErrorStateMatcher(): void { + this.errorStateMatcher = { + isErrorState: (_control: UntypedFormControl | null, _form: FormGroupDirective | NgForm | null): boolean => + !this.field.isValid && this.isTouched() + }; + } + + private updateTranslateParameters(): void { + if (this.field.validationSummary?.isActive()) { + this.translateParameters = this.field.validationSummary.getAttributesAsJsonObj(); + } else { + this.translateParameters = {}; + } + } + + onBlur(): void { + this.markAsTouched(); + this.updateTranslateParameters(); + } + + onTextFieldChanged(): void { + this.onFieldChanged(this.field); + this.updateTranslateParameters(); } }