An open API service indexing awesome lists of open source software.

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.

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';
});
}
}
```