diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html index 9f4d403..444bfea 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html @@ -32,15 +32,11 @@ afPlaceholder="Välj orsak till avvikelse" [afSelectItems]="reason" [afRequired]="true" + [afInvalidMessage]="reasonFormControl.errors?.required" [afAnnounceIfOptional]="true" [afDisableValidStyle]="true" [afInvalid]="formControlIsInvalid(reasonFormControl)" > -
- {{reasonFormControl.errors?.required}} - -
-
- {{question.errors?.required}} - -
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts index 7f952aa..413c84c 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts @@ -8,6 +8,8 @@ import { CustomError } from '@msfa-models/error/custom-error'; import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; +import { RegexValidator } from '@msfa-utils/validators/regex.validator'; import { RequiredValidator } from '@msfa-validators/required.validator'; import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { map, shareReplay, switchMap, take } from 'rxjs/operators'; @@ -48,9 +50,9 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { shareReplay(1) ); - reasons$ = this.deltagareAvvikelseService.getAvvikelseOrsaker$; + reasons$: Observable = this.deltagareAvvikelseService.getAvvikelseOrsaker$; reasonsAsNgDigiFormSelectItems$: Observable = this.reasons$.pipe( - map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id }))) + map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id as string }))) ); allAvvikelseQuestions$ = this.deltagareAvvikelseService.fragorForAvvikelser$; @@ -63,8 +65,8 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { private subscriptions: Subscription[] = []; private todayDateISO = new Date().toISOString().slice(0, 10); avvikelseFormGroup = new FormGroup({ - [this.reasonFormName]: new FormControl(null, RequiredValidator('Orsak är obligatorisk')), - [this.reportingDateFormName]: new FormControl(this.todayDateISO, RequiredValidator('Datum är obligatoriskt')), + [this.reasonFormName]: new FormControl(null, [RequiredValidator('Orsak är obligatorisk')]), + [this.reportingDateFormName]: new FormControl(this.todayDateISO, [RequiredValidator('Datum är obligatoriskt')]), [this.questionsFormName]: new FormArray([]), }); private formData$: Observable = this.avvikelseFormGroup @@ -141,6 +143,8 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { openConfirmDialog(): void { this.shouldValidate$.next(true); + markControlsAsDirty(Object.values(this.avvikelseFormGroup.controls)); + this.avvikelseFormGroup.markAllAsTouched(); if (this.avvikelseFormGroup.valid) { this.confirmDialogIsOpen$.next(true); @@ -184,7 +188,7 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { svar: question, })), rapporteringsdatum: formData.reportingDate, - }; + } as AvvikelseAlternativ; return { genomforandeReferens, avvikelseAlternativ }; } @@ -199,7 +203,12 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { this.currentQuestions.push(question); this.questionsFormArray.push( - new FormControl('', this.questionIsRequired(question) ? RequiredValidator('Frågan är obligatorisk') : null) + new FormControl( + '', + this.questionIsRequired(question) + ? [RequiredValidator('Frågan är obligatorisk'), RegexValidator()] + : [RegexValidator()] + ) ); } } diff --git a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts index 6949a19..03cbae6 100644 --- a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts +++ b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts @@ -1,2 +1,3 @@ export const EMAIL_REGEX = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/; export const ISO_DATE_NO_TIME = /^\d{4}[-/\s]?((((0[13578])|(1[02]))[-/\s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[-/\s]?(([0-2][0-9])|(30)))|(02[-/\s]?[0-2][0-9]))$/; +export const CHARACTER_REGEX = /\w/; diff --git a/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts b/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts new file mode 100644 index 0000000..5c5ace5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts @@ -0,0 +1,13 @@ +import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; + +export function markControlsAsDirty(controls: AbstractControl[]): void { + controls.forEach(control => { + if (control instanceof FormControl) { + control.markAsDirty({ onlySelf: true }); + } else if (control instanceof FormGroup) { + markControlsAsDirty(Object.values(control.controls)); + } else if (control instanceof FormArray) { + markControlsAsDirty(control.controls); + } + }); +} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts new file mode 100644 index 0000000..446f63e --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts @@ -0,0 +1,15 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { CHARACTER_REGEX } from '@msfa-constants/regex'; +import { ValidationError } from '@msfa-models/validation-error.model'; + +export function RegexValidator(regex = CHARACTER_REGEX, message = 'Ogiltig värde'): ValidatorFn { + return (control: AbstractControl): ValidationError => { + if (control && control.value) { + if (!regex.test(control.value)) { + return { invalid: message }; + } + } + + return null; + }; +}