Skip to content

Instantly share code, notes, and snippets.

@ntziolis
Created February 15, 2020 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ntziolis/579a235a43f22b29fe50ebed06f67633 to your computer and use it in GitHub Desktop.
Save ntziolis/579a235a43f22b29fe50ebed06f67633 to your computer and use it in GitHub Desktop.
import { FormArray, FormControl, Validators } from '@angular/forms';
import {
ArrayPropertyKey,
ArrayPropertyValue,
NgxFormWithArrayControls
} from 'ngx-sub-form';
import {
NgxSingleFieldSubFormComponent,
WrappedControlForm
} from './ngx-single-field-sub-form.component';
export interface ArrayOptions {
initial: number;
min: number;
max?: number;
}
const defaultOptions: ArrayOptions = {
initial: 1,
min: 1
};
export abstract class NgxArraySubFormComponent<FormInterface>
extends NgxSingleFieldSubFormComponent<FormInterface[]>
implements NgxFormWithArrayControls<WrappedControlForm<FormInterface[]>> {
abstract getDefaultValue(): FormInterface;
private _options: ArrayOptions;
protected getOptions(): Partial<ArrayOptions> {
return defaultOptions;
}
protected get options(): ArrayOptions {
if (!this._options) {
this._options = { ...defaultOptions, ...this.getOptions() };
}
return this._options;
}
public createFormArrayControl(
key: ArrayPropertyKey<WrappedControlForm<FormInterface[]>> | undefined,
value: ArrayPropertyValue<WrappedControlForm<FormInterface[]>>
): FormControl {
return new FormControl(value);
}
public get formArray(): FormArray {
return this.formGroupControls.innerControl;
}
public get formArrayName(): string {
return this.formControlNames.innerControl;
}
public get formArrayErrors(): any {
return (this.formGroupErrors || {}).innerControl || {};
}
public get canAddItem(): boolean {
return (
!this.options.max ||
this.formGroupControls.innerControl.length < this.options.max
);
}
public get canRemoveItem(): boolean {
return this.formGroupControls.innerControl.length > this.options.min;
}
public addItem(value: FormInterface = null) {
this.formArray.push(
this.createFormArrayControl(
'innerControl',
value || this.getDefaultValue()
)
);
}
public removeItem(index: number) {
this.formArray.removeAt(index);
}
public getDefaultValues() {
const items: FormInterface[] = [];
for (let i = 0; i < this.options.initial; i++) {
items.push(this.getDefaultValue());
}
return {
innerControl: items
};
}
getFormControl() {
const controls: FormControl[] = [];
for (let i = 0; i < this.options.initial; i++) {
controls.push(
this.createFormArrayControl('innerControl', this.getDefaultValue())
);
}
const validators = [Validators.minLength(this.options.min)];
if (this.options.max) {
validators.push(Validators.maxLength(this.options.min));
}
return new FormArray(controls, validators);
}
protected transformToFormGroup(
innerControl: FormInterface[]
): WrappedControlForm<FormInterface[]> {
// form array value always has to be an array (not null or undefined)
// use default values when innerControl value not set
if (!innerControl) {
return this.getDefaultValues();
}
return super.transformToFormGroup(innerControl);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment