All files / lib/dynamic-form-group dynamic-form-group.ts

100% Statements 44/44
100% Branches 11/11
100% Functions 25/25
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                    252x           253x     253x 252x 251x     1x   166x 14x     46x 46x 46x       22x       2x       2x       2x 1x 1x   2x         1x 2x       48x       59x       60x 59x 59x 23x         27x 26x       26x 2x   24x       63x 30x 23x   7x 4x   3x        
import { DynamicFormElement } from '../dynamic-form-element/dynamic-form-element';
import { DynamicFormField } from '../dynamic-form-field/dynamic-form-field';
import { DynamicFormFieldClassType } from '../dynamic-form-field/dynamic-form-field-class-type';
import { FormGroupBase } from '../dynamic-form-field/dynamic-form-field-control';
import { DynamicFormFieldType } from '../dynamic-form-field/dynamic-form-field-type';
import { DynamicForm } from '../dynamic-form/dynamic-form';
import { DynamicFormBuilder } from '../dynamic-form/dynamic-form.builder';
import { DynamicFormGroupDefinition } from './dynamic-form-group-definition';
import { DynamicFormGroupTemplate } from './dynamic-form-group-template';
import { DynamicFormGroupAsyncValidator, DynamicFormGroupValidator } from './dynamic-form-group-validator';
 
export class DynamicFormGroup<
  Value extends { [key: string]: any } = any, Model extends Value = Value,
  Template extends DynamicFormGroupTemplate = DynamicFormGroupTemplate,
  Definition extends DynamicFormGroupDefinition<Value, Template> = DynamicFormGroupDefinition<Value, Template>,
  Type extends DynamicFormFieldType = DynamicFormFieldType
> extends DynamicFormField<Value, Model, FormGroupBase<Value>, Template, Definition, Type> {
 
  protected _fields: DynamicFormField[] = [];
 
  constructor(builder: DynamicFormBuilder, root: DynamicForm, parent: DynamicFormElement, definition: Definition, type: Type);
  /** @internal */
  constructor(builder: DynamicFormBuilder, definition: Definition, model: Model);
  constructor(builder: DynamicFormBuilder, ...params: any[]) {
    const { root, parent, definition, type, model } = params.length === 4
      ? { root: params[0], parent: params[1], definition: params[2], type: params[3], model: null }
      : { root: null, parent: null, definition: params[0], type: null, model: params[1] };
    super(builder, root, parent, definition, type, new FormGroupBase<Value>({} as any));
    this._model = model || this.getModel();
    this._parameters = {};
  }
 
  get fieldClassType(): DynamicFormFieldClassType { return 'group'; }
 
  override get children(): DynamicFormElement[] { return this._children; }
  get fields(): DynamicFormField[] { return this._fields; }
 
  check(): void {
    this.checkControl();
    this.checkValidators();
    this._fields.forEach(field => field.check());
  }
 
  destroy(): void {
    this._fields.forEach(field => field.destroy());
  }
 
  reset(): void {
    this._fields.forEach(field => field.reset());
  }
 
  resetEmpty(): void {
    this._fields.forEach(field => field.resetEmpty());
  }
 
  resetDefault(): void {
    if (this.defaultValue) {
      const defaultModel = this.cloneObject(this.defaultValue);
      this._control.patchValue(defaultModel);
    } else {
      this._fields.forEach(field => field.resetDefault());
    }
  }
 
  validate(): void {
    this._control.markAsTouched();
    this._fields.forEach(field => field.validate());
  }
 
  protected getChildren(): DynamicFormElement[] {
    return this._builder.createFormElements(this.root, this, this.definition.children);
  }
 
  protected getValidators(): (DynamicFormGroupValidator | DynamicFormGroupAsyncValidator)[] {
    return this._builder.createGroupValidators(this);
  }
 
  protected override initChildren(): void {
    super.initChildren();
    this._fields = this.filterFields(this._children);
    this._fields.filter(field => !field.unregistered).forEach(field => {
      this._control.registerControl(field.definition.key, field.control);
    });
  }
 
  private getModel(): Model {
    this.parentField.model[this.key] = this.parentField.model[this.key] || this.getDefaultModel();
    return this.parentField.model[this.key];
  }
 
  private getDefaultModel(): Model {
    if (this.defaultValue) {
      return this.cloneObject<Model>(this.defaultValue as Model);
    }
    return {} as Model;
  }
 
  private filterFields(elements: DynamicFormElement[]): DynamicFormField[] {
    return elements.reduce((result, element) => {
      if (element.classType === 'field') {
        return result.concat(element as DynamicFormField);
      }
      if (element.children) {
        return result.concat(this.filterFields(element.children));
      }
      return result;
    }, [] as DynamicFormField[]);
  }
}