diff options
Diffstat (limited to 'client/src/app/shared/shared-forms/form-reactive.ts')
-rw-r--r-- | client/src/app/shared/shared-forms/form-reactive.ts | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-forms/form-reactive.ts b/client/src/app/shared/shared-forms/form-reactive.ts new file mode 100644 index 000000000..caa31d831 --- /dev/null +++ b/client/src/app/shared/shared-forms/form-reactive.ts | |||
@@ -0,0 +1,69 @@ | |||
1 | import { FormGroup } from '@angular/forms' | ||
2 | import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from './form-validators' | ||
3 | |||
4 | export type FormReactiveErrors = { [ id: string ]: string | FormReactiveErrors } | ||
5 | export type FormReactiveValidationMessages = { | ||
6 | [ id: string ]: { [ name: string ]: string } | FormReactiveValidationMessages | ||
7 | } | ||
8 | |||
9 | export abstract class FormReactive { | ||
10 | protected abstract formValidatorService: FormValidatorService | ||
11 | protected formChanged = false | ||
12 | |||
13 | form: FormGroup | ||
14 | formErrors: any // To avoid casting in template because of string | FormReactiveErrors | ||
15 | validationMessages: FormReactiveValidationMessages | ||
16 | |||
17 | buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) { | ||
18 | const { formErrors, validationMessages, form } = this.formValidatorService.buildForm(obj, defaultValues) | ||
19 | |||
20 | this.form = form | ||
21 | this.formErrors = formErrors | ||
22 | this.validationMessages = validationMessages | ||
23 | |||
24 | this.form.valueChanges.subscribe(() => this.onValueChanged(this.form, this.formErrors, this.validationMessages, false)) | ||
25 | } | ||
26 | |||
27 | protected forceCheck () { | ||
28 | return this.onValueChanged(this.form, this.formErrors, this.validationMessages, true) | ||
29 | } | ||
30 | |||
31 | protected check () { | ||
32 | return this.onValueChanged(this.form, this.formErrors, this.validationMessages, false) | ||
33 | } | ||
34 | |||
35 | private onValueChanged ( | ||
36 | form: FormGroup, | ||
37 | formErrors: FormReactiveErrors, | ||
38 | validationMessages: FormReactiveValidationMessages, | ||
39 | forceCheck = false | ||
40 | ) { | ||
41 | for (const field of Object.keys(formErrors)) { | ||
42 | if (formErrors[field] && typeof formErrors[field] === 'object') { | ||
43 | this.onValueChanged( | ||
44 | form.controls[field] as FormGroup, | ||
45 | formErrors[field] as FormReactiveErrors, | ||
46 | validationMessages[field] as FormReactiveValidationMessages, | ||
47 | forceCheck | ||
48 | ) | ||
49 | continue | ||
50 | } | ||
51 | |||
52 | // clear previous error message (if any) | ||
53 | formErrors[ field ] = '' | ||
54 | const control = form.get(field) | ||
55 | |||
56 | if (control.dirty) this.formChanged = true | ||
57 | |||
58 | // Don't care if dirty on force check | ||
59 | const isDirty = control.dirty || forceCheck === true | ||
60 | if (control && isDirty && control.enabled && !control.valid) { | ||
61 | const messages = validationMessages[ field ] | ||
62 | for (const key of Object.keys(control.errors)) { | ||
63 | formErrors[ field ] += messages[ key ] + ' ' | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | } | ||