https://github.com/seregpie/ngx-advanced-forms
Everything to make your work with Angular forms easier.
https://github.com/seregpie/ngx-advanced-forms
angular array bridge control form record service util validation
Last synced: 5 months ago
JSON representation
Everything to make your work with Angular forms easier.
- Host: GitHub
- URL: https://github.com/seregpie/ngx-advanced-forms
- Owner: SeregPie
- License: mit
- Created: 2022-10-07T12:32:44.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-06T08:06:07.000Z (about 1 year ago)
- Last Synced: 2024-11-16T18:48:02.414Z (6 months ago)
- Topics: angular, array, bridge, control, form, record, service, util, validation
- Language: TypeScript
- Homepage:
- Size: 150 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# NgxAdvancedForms
Everything to make your work with Angular forms easier.
## Setup
```sh
npm i ngx-advanced-forms
```---
```ts
import {
DynamicFormArray,
withCustomValidator,
/* ... */
} from 'ngx-advanced-forms';
```## API
- **`C`** [DynamicFormArray](#dynamicformarray)
- **`C`** [DynamicFormRecord](#dynamicformrecord)
- **`C`** [FormControlService](#formcontrolservice)
- **`C`** [FallthroughFormService](#fallthroughformservice)
- **`T`** [CustomValidatorFn](#customvalidatorfn)
- **`T`** [CustomAsyncValidatorFn](#customasyncvalidatorfn)
- **`F`** [withCustomValidator](#withcustomvalidator)
- **`F`** [withCustomAsyncValidator](#withcustomasyncvalidator)
- **`F`** [composeValidators](#composevalidators)
- **`T`** [ControlStateAccessor](#controlstateaccessor)
- **`T`** [CreateControlStateAccessorFn](#createcontrolstateaccessorfn)
- **`F`** [updateFormState](#updateformstate)### DynamicFormArray
A sup-class of `FormArray` that creates or removes sub-controls dynamically based on the passed value.
#### Type
```ts
class DynamicFormArray extends FormArray {
constructor(controlFactory: () => TControl, options?: AbstractControlOptions);
}
```### DynamicFormRecord
A sup-class of `FormRecord` that creates or removes sub-controls dynamically based on the passed value.
#### Type
```ts
class DynamicFormRecord extends FormRecord {
constructor(controlFactory: () => TControl, options?: AbstractControlOptions);
}
```### FormControlService
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;
}
```### FallthroughFormService
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: `
`,
selector: 'my-percent-input',
})
class MyPercentInputComponent {
constructor(public fallthroughFormService: FallthroughFormService) {}get form() {
return this.fallthroughFormService.control as FormControl;
}@Input()
label: string = '';
}
```### CustomValidatorFn
#### Type
```ts
interface CustomValidatorFn {
(control: TControl): null | ValidationErrors;
}
```### CustomAsyncValidatorFn
#### Type
```ts
interface CustomAsyncValidatorFn {
(control: TControl): Promise | Observable;
}
```### withCustomValidator
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;
},
),
});
```### withCustomAsyncValidator
Adds a typed asynchronous validator to a control.
#### Type
```ts
function withCustomAsyncValidator(
control: TControl,
validator: CustomAsyncValidatorFn,
): TControl;
```#### Details
- Behaves the same as `withCustomValidator`.
### composeValidators
Composes multiple validators into one.
#### Type
```ts
function composeValidators(
validators: Array>,
): CustomValidatorFn;
```#### Usage
```ts
const form = new FormControl(null, {
validators: composeValidators([
Validators.required,
Validators.min(0),
Validators.max(100),
]),
});
```### ControlStateAccessor
#### Type
```ts
interface ControlStateAccessor {
readonly control: TControl;get disabled(): boolean;
set disabled(v: boolean);get enabled(): boolean;
set enabled(v: boolean);
}
```### CreateControlStateAccessorFn
#### Type
```ts
interface CreateControlStateAccessorFn {
(control: TControl): ControlStateAccessor;
}
```### updateFormState
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(null),
valueInFeet: new FormControl(null),
});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';
});
}
}
```