Everything to make your work with Angular forms easier.
npm install ngx-advanced-formsEverything to make your work with Angular forms easier.
``sh`
npm i ngx-advanced-forms
---
`ts`
import {
DynamicFormArray,
withCustomValidator,
/ ... /
} from 'ngx-advanced-forms';
- C DynamicFormArray
- C DynamicFormRecord
- C FormControlService
- C FallthroughFormService
- T CustomValidatorFn
- T CustomAsyncValidatorFn
- F withCustomValidator
- F withCustomAsyncValidator
- F composeValidators
- T ControlStateAccessor
- T CreateControlStateAccessorFn
- F updateFormState
A sup-class of FormArray that creates or removes sub-controls dynamically based on the passed value.
#### Type
`ts`
class DynamicFormArray
constructor(controlFactory: () => TControl, options?: AbstractControlOptions);
}
A sup-class of FormRecord that creates or removes sub-controls dynamically based on the passed value.
#### Type
`ts`
class DynamicFormRecord
constructor(controlFactory: () => TControl, options?: AbstractControlOptions);
}
Implements all necessary tools to connect to the overlying control.
#### Type
`ts
@Injectable()
class FormControlService
static provide(): Provider;
get value(): null | TValue;
set value(v: null | TValue);
readonly valueChanges: Observable
get disabled(): boolean;
readonly disabledChanges: Observable
get errors(): null | ValidationErrors;
set errors(v: null | ValidationErrors);
readonly errorsChanges: Observable
get pending(): boolean;
set pending(v: boolean);
readonly pendingChanges: Observable
touch(): void;
readonly touchEvents: Observable
}
`
Passes a control from a control directive through.
#### Type
`ts
@Injectable()
class FallthroughFormService {
static provide(): Provider;
readonly controlDirective: null | AbstractControlDirective;
readonly control: null | AbstractControl;
}
`
#### Details
- Works with any reactive and non-reactive control directive.
- The control is available after the component is initialized.
#### Usage
`ts
@Component({
imports: [ReactiveFormsModule, MyNumberInputComponent],
providers: [FallthroughFormService.provide()],
standalone: true,
template:
[label]="label"
[max]="100"
[min]="0"
[step]="0.1"
unit="%"
/>
,
selector: 'my-percent-input',
})
class MyPercentInputComponent {
constructor(public fallthroughFormService: FallthroughFormService) {}
get form() {
return this.fallthroughFormService.control as FormControl;
}
@Input()
label: string = '';
}
`
#### Type
`ts`
interface CustomValidatorFn
(control: TControl): null | ValidationErrors;
}
#### Type
`ts`
interface CustomAsyncValidatorFn
(control: TControl): Promise
}
Adds a typed validator to a control.
#### Type
`ts`
function withCustomValidator
control: TControl,
validator: CustomValidatorFn
): TControl;
#### Details
- Recalculates the validation status of the control.
#### Usage
`ts`
const form = new FormGroup({
email: new FormControl
validators: [Validators.required, Validators.email],
}),
password: withCustomValidator(
new FormGroup({
actual: new FormControl
validators: [Validators.required, Validators.minLength(8)],
}),
verify: new FormControl
}),
(form) => {
if (form.controls.actual.valid) {
if (form.controls.actual.value !== form.controls.verify.value) {
return {verifyPassword: true};
}
}
return null;
},
),
});
Adds a typed asynchronous validator to a control.
#### Type
`ts`
function withCustomAsyncValidator
control: TControl,
validator: CustomAsyncValidatorFn
): TControl;
#### Details
- Behaves the same as withCustomValidator.
Composes multiple validators into one.
#### Type
`ts`
function composeValidators
validators: Array
): CustomValidatorFn
#### Usage
`ts`
const form = new FormControl
validators: composeValidators([
Validators.required,
Validators.min(0),
Validators.max(100),
]),
});
#### Type
`ts
interface ControlStateAccessor
readonly control: TControl;
get disabled(): boolean;
set disabled(v: boolean);
get enabled(): boolean;
set enabled(v: boolean);
}
`
#### Type
`ts`
interface CreateControlStateAccessorFn {
}
Provides a convenient way to manage the enabled/disabled state of multiple nested controls.
#### Type
`ts`
function updateFormState
control: TControl,
fn: {(wrap: CreateControlStateAccessorFn): void},
): void;
#### Details
- Accepts only the provided control and its descendants.
- The order of the statements doesn't matter.
- Prevents unnecessary events from being emitted when no changes are detected.
#### Usage
`ts
class {
form = new FormGroup({
unit: new FormControl<'meter' | 'feet'>('meter'),
valueInMeters: new FormControl
valueInFeet: new FormControl
});
ngAfterContentChecked(): void {
const {form} = this;
updateFormState(form, (wrap) => {
const {unit} = form.getRawValue();
wrap(form.controls.valueInMeters).enabled = unit === 'meter';
wrap(form.controls.valueInFeet).enabled = unit === 'feet';
});
}
}
``