Skip to content
Snippets Groups Projects
Commit 1dcfad9c authored by jojohoch's avatar jojohoch
Browse files

[player] Show different validation warnings

* Move setting of validators from `FormElementComponent` to
`ValidationMessageComponent`
* Add validators and warnings to `ValidationMessageComponent`
* Move subscriptions for form controls and their validators from
`PageComponent` to `FormComponent`
parent 72965847
No related branches found
No related tags found
No related merge requests found
...@@ -2,7 +2,7 @@ import { ...@@ -2,7 +2,7 @@ import {
Directive, EventEmitter, OnDestroy, OnInit, Output Directive, EventEmitter, OnDestroy, OnInit, Output
} from '@angular/core'; } from '@angular/core';
import { import {
FormControl, FormGroup, ValidatorFn, Validators FormControl, FormGroup
} from '@angular/forms'; } from '@angular/forms';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { pairwise, startWith, takeUntil } from 'rxjs/operators'; import { pairwise, startWith, takeUntil } from 'rxjs/operators';
...@@ -40,22 +40,6 @@ export abstract class FormElementComponent extends ElementComponent implements O ...@@ -40,22 +40,6 @@ export abstract class FormElementComponent extends ElementComponent implements O
this.formValueChanged.emit({ id: this.elementModel.id, values: [prevValue, nextValue] }); this.formValueChanged.emit({ id: this.elementModel.id, values: [prevValue, nextValue] });
} }
}); });
// TODO: find better solution
setTimeout((): void => {
this.formService.setValidators({
id: this.elementModel.id,
validators: this.validators,
formGroup: this.parentForm
});
});
}
private get validators(): ValidatorFn[] {
const validators: ValidatorFn[] = [];
if (this.elementModel.required) {
validators.push(Validators.required);
}
return validators;
} }
private get formControl(): FormControl { private get formControl(): FormControl {
......
...@@ -42,6 +42,6 @@ export class FormService { ...@@ -42,6 +42,6 @@ export class FormService {
} }
setValidators(validations: FormControlValidators): void { setValidators(validations: FormControlValidators): void {
this._validationsAdded.next(validations); Promise.resolve().then(() => this._validationsAdded.next(validations));
} }
} }
...@@ -5,7 +5,9 @@ import { takeUntil } from 'rxjs/operators'; ...@@ -5,7 +5,9 @@ import { takeUntil } from 'rxjs/operators';
import { FormService } from '../../../../common/form.service'; import { FormService } from '../../../../common/form.service';
import { VeronaSubscriptionService } from '../services/verona-subscription.service'; import { VeronaSubscriptionService } from '../services/verona-subscription.service';
import { VeronaPostService } from '../services/verona-post.service'; import { VeronaPostService } from '../services/verona-post.service';
import { FormGroupPage, ValueChangeElement } from '../../../../common/form'; import {
FormControlElement, FormControlValidators, FormGroupPage, ValueChangeElement
} from '../../../../common/form';
import { import {
PlayerConfig, UnitState, VopNavigationDeniedNotification PlayerConfig, UnitState, VopNavigationDeniedNotification
} from '../models/verona'; } from '../models/verona';
...@@ -50,6 +52,12 @@ export class FormComponent implements OnDestroy { ...@@ -50,6 +52,12 @@ export class FormComponent implements OnDestroy {
this.formService.groupAdded this.formService.groupAdded
.pipe(takeUntil(this.ngUnsubscribe)) .pipe(takeUntil(this.ngUnsubscribe))
.subscribe((group: FormGroupPage): void => this.addGroup(group)); .subscribe((group: FormGroupPage): void => this.addGroup(group));
this.formService.controlAdded.pipe(
takeUntil(this.ngUnsubscribe)
).subscribe((control: FormControlElement): void => this.addControl(control));
this.formService.validationsAdded.pipe(
takeUntil(this.ngUnsubscribe)
).subscribe((validations: FormControlValidators): void => this.setValidators(validations));
this.veronaSubscriptionService.vopNavigationDeniedNotification this.veronaSubscriptionService.vopNavigationDeniedNotification
.pipe(takeUntil(this.ngUnsubscribe)) .pipe(takeUntil(this.ngUnsubscribe))
.subscribe((message: VopNavigationDeniedNotification): void => this.onNavigationDenied(message)); .subscribe((message: VopNavigationDeniedNotification): void => this.onNavigationDenied(message));
...@@ -58,6 +66,15 @@ export class FormComponent implements OnDestroy { ...@@ -58,6 +66,15 @@ export class FormComponent implements OnDestroy {
.subscribe((formValues: { pages: Record<string, string>[] }): void => this.onFormChanges(formValues)); .subscribe((formValues: { pages: Record<string, string>[] }): void => this.onFormChanges(formValues));
} }
private addControl = (control: FormControlElement): void => {
control.formGroup.addControl(control.id, control.formControl);
};
private setValidators = (validators: FormControlValidators): void => {
validators.formGroup.controls[validators.id].setValidators(validators.validators);
validators.formGroup.controls[validators.id].updateValueAndValidity();
};
private onNavigationDenied(message: VopNavigationDeniedNotification): void { private onNavigationDenied(message: VopNavigationDeniedNotification): void {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('player: onNavigationDenied', message); console.log('player: onNavigationDenied', message);
......
import { import {
Component, Input, OnDestroy, OnInit Component, Input, OnInit
} from '@angular/core'; } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { UnitPage } from '../../../../common/unit'; import { UnitPage } from '../../../../common/unit';
import { FormService } from '../../../../common/form.service'; import { FormService } from '../../../../common/form.service';
import { FormControlElement, FormControlValidators } from '../../../../common/form';
@Component({ @Component({
selector: 'app-page', selector: 'app-page',
...@@ -25,46 +22,15 @@ import { FormControlElement, FormControlValidators } from '../../../../common/fo ...@@ -25,46 +22,15 @@ import { FormControlElement, FormControlValidators } from '../../../../common/fo
` `
}) })
export class PageComponent implements OnInit, OnDestroy { export class PageComponent implements OnInit {
@Input() page!: UnitPage; @Input() page!: UnitPage;
@Input() parentForm!: FormGroup; @Input() parentForm!: FormGroup;
pageForm!: FormGroup; pageForm!: FormGroup;
private ngUnsubscribe = new Subject<void>();
constructor(private formService: FormService) {} constructor(private formService: FormService) {}
ngOnInit(): void { ngOnInit(): void {
this.pageForm = new FormGroup({}); this.pageForm = new FormGroup({});
this.formService.registerFormGroup({ id: this.page.id, formGroup: this.pageForm }); this.formService.registerFormGroup({ id: this.page.id, formGroup: this.pageForm });
this.initSubscriptions();
}
private initSubscriptions(): void {
this.formService.controlAdded.pipe(
takeUntil(this.ngUnsubscribe)
).subscribe((control: FormControlElement): void => this.addControl(control));
this.formService.validationsAdded.pipe(
takeUntil(this.ngUnsubscribe)
).subscribe((validations: FormControlValidators): void => this.setValidators(validations));
}
private addControl(control: FormControlElement): void {
// we need to check that the control belongs to the page
if (this.pageForm === control.formGroup) {
this.pageForm.addControl(control.id, control.formControl);
}
}
private setValidators(validators: FormControlValidators): void {
// we need to check that the control belongs to the page
if (this.pageForm === validators.formGroup) {
this.pageForm.controls[validators.id].setValidators(validators.validators);
this.pageForm.controls[validators.id].updateValueAndValidity();
}
}
ngOnDestroy(): void {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
} }
} }
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'; import {
import { InputUIElement, UnitUIElement } from '../../../../common/unit'; FormControl, FormGroup, ValidatorFn, Validators
} from '@angular/forms';
import {
InputUIElement, NumberFieldElement, TextFieldElement, UnitUIElement
} from '../../../../common/unit';
import { FormService } from '../../../../common/form.service';
@Component({ @Component({
selector: 'app-error-message', selector: 'app-error-message',
template: ` template: `
<mat-error *ngIf="formElementControl && formElementControl.touched && formElementControl.errors"> <ng-container *ngIf="formElementControl && formElementControl.touched">
{{requiredMessage}} <mat-error *ngIf="formElementControl.errors?.required">
</mat-error> {{requiredMessage}}
</mat-error>
<mat-error *ngIf="formElementControl.errors?.minlength">
{{minLengthMessage}}
</mat-error>
<mat-error *ngIf="formElementControl.errors?.maxlength">
{{maxLengthMessage}}
</mat-error>
<mat-error *ngIf="formElementControl.errors?.min">
{{minMessage}}
</mat-error>
<mat-error *ngIf="formElementControl.errors?.max">
{{maxMessage}}
</mat-error>
</ng-container>
` `
}) })
...@@ -16,12 +35,56 @@ export class ValidationMessageComponent implements OnInit { ...@@ -16,12 +35,56 @@ export class ValidationMessageComponent implements OnInit {
parentForm!: FormGroup; parentForm!: FormGroup;
formElementControl!: FormControl; formElementControl!: FormControl;
constructor(private formService: FormService) {}
ngOnInit(): void { ngOnInit(): void {
this.formElementControl = this.parentForm.controls[this.elementModel.id] as FormControl; this.formElementControl = this.parentForm.controls[this.elementModel.id] as FormControl;
this.formService.setValidators({
id: this.elementModel.id,
validators: this.validators,
formGroup: this.parentForm
});
}
private get validators(): ValidatorFn[] {
const validators: ValidatorFn[] = [];
if (this.elementModel.required) {
validators.push(Validators.required);
}
if (this.elementModel.min) {
if (this.elementModel.type === 'number_field') {
validators.push(Validators.min(<number> this.elementModel.min));
} else {
validators.push(Validators.minLength(<number> this.elementModel.min));
}
}
if (this.elementModel.max) {
if (this.elementModel.type === 'number_field') {
validators.push(Validators.max(<number> this.elementModel.max));
} else {
validators.push(Validators.maxLength(<number> this.elementModel.maxLength));
}
}
return validators;
} }
// eslint-disable-next-line class-methods-use-this
get requiredMessage(): string { get requiredMessage(): string {
return (this.elementModel as InputUIElement).validationWarnMessage || 'Wert muss angegeben werden'; return (this.elementModel as InputUIElement).requiredWarnMessage || 'Eingabe erforderlich';
}
get minLengthMessage(): string {
return (this.elementModel as TextFieldElement).minWarnMessage || 'Eingabe zu kurz';
}
get maxLengthMessage(): string {
return (this.elementModel as TextFieldElement).maxWarnMessage || 'Eingabe zu lang';
}
get minMessage(): string {
return (this.elementModel as NumberFieldElement).minWarnMessage || 'Wert zu klein';
}
get maxMessage(): string {
return (this.elementModel as NumberFieldElement).maxWarnMessage || 'Wert zu groß';
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment