import { FormGroup } from '@angular/forms'
+import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
+
+export type FormReactiveErrors = { [ id: string ]: string | FormReactiveErrors }
+export type FormReactiveValidationMessages = {
+ [ id: string ]: { [ name: string ]: string } | FormReactiveValidationMessages
+}
export abstract class FormReactive {
- abstract form: FormGroup
- abstract formErrors: Object
- abstract validationMessages: Object
+ protected abstract formValidatorService: FormValidatorService
+ protected formChanged = false
- abstract buildForm (): void
+ form: FormGroup
+ formErrors: FormReactiveErrors
+ validationMessages: FormReactiveValidationMessages
- protected onValueChanged (data?: any) {
- for (const field in this.formErrors) {
- // clear previous error message (if any)
- this.formErrors[field] = ''
- const control = this.form.get(field)
+ buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
+ const { formErrors, validationMessages, form } = this.formValidatorService.buildForm(obj, defaultValues)
- if (control && control.dirty && !control.valid) {
- const messages = this.validationMessages[field]
- for (const key in control.errors) {
- this.formErrors[field] += messages[key] + ' '
- }
- }
- }
+ this.form = form
+ this.formErrors = formErrors
+ this.validationMessages = validationMessages
+
+ this.form.valueChanges.subscribe(() => this.onValueChanged(this.form, this.formErrors, this.validationMessages, false))
}
- // Same as onValueChanged but force checking even if the field is not dirty
protected forceCheck () {
- for (const field in this.formErrors) {
+ return this.onValueChanged(this.form, this.formErrors, this.validationMessages, true)
+ }
+
+ protected check () {
+ return this.onValueChanged(this.form, this.formErrors, this.validationMessages, false)
+ }
+
+ private onValueChanged (
+ form: FormGroup,
+ formErrors: FormReactiveErrors,
+ validationMessages: FormReactiveValidationMessages,
+ forceCheck = false
+ ) {
+ for (const field of Object.keys(formErrors)) {
+ if (formErrors[field] && typeof formErrors[field] === 'object') {
+ this.onValueChanged(
+ form.controls[field] as FormGroup,
+ formErrors[field] as FormReactiveErrors,
+ validationMessages[field] as FormReactiveValidationMessages,
+ forceCheck
+ )
+ continue
+ }
+
// clear previous error message (if any)
- this.formErrors[field] = ''
- const control = this.form.get(field)
+ formErrors[ field ] = ''
+ const control = form.get(field)
- if (control && !control.valid) {
- const messages = this.validationMessages[field]
+ if (control.dirty) this.formChanged = true
+
+ // Don't care if dirty on force check
+ const isDirty = control.dirty || forceCheck === true
+ if (control && isDirty && !control.valid) {
+ const messages = validationMessages[ field ]
for (const key in control.errors) {
- this.formErrors[field] += messages[key] + ' '
+ formErrors[ field ] += messages[ key ] + ' '
}
}
}
}
+
}