Created
February 15, 2020 15:41
-
-
Save ntziolis/579a235a43f22b29fe50ebed06f67633 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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