Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/davidwalschots/angular-reactive-validation

Reactive Forms validation shouldn't require the developer to write lots of HTML to show validation messages. This library makes it easy.
https://github.com/davidwalschots/angular-reactive-validation

angular reactive-forms validation

Last synced: 5 days ago
JSON representation

Reactive Forms validation shouldn't require the developer to write lots of HTML to show validation messages. This library makes it easy.

Awesome Lists containing this project

README

        

# Angular Reactive Validation

Reactive Forms validation shouldn't require the developer to write lots of HTML to show validation messages. This library makes it easy.

## Table of contents

* [Installation](#installation)
* [Compatibility](#compatibility)
* [Basic usage](#basic-usage)
* [Advanced validation declaration](#advanced-validation-declaration)
* [Changing when validation messages are displayed](#changing-when-validation-messages-are-displayed)
* [Declaring your own validator functions](#declaring-your-own-validator-functions)
* [Edge use cases](#edge-use-cases)
* [Handling custom HTML validation messages](#handling-custom-html-validation-messages)
* [Using arv-validation-messages when not using `[formGroup]` or `formGroupName` attributes](#using-arv-validation-messages-when-not-using-formgroup-or-formgroupname-attributes)

## Installation

To install this library, run:

```bash
npm install angular-reactive-validation --save
```

## Compatibility
| Angular version | Package version |
|-----------------|-----------------|
| 18 | 12.x |
| 17 | 11.x |
| 16 | 10.x |
| 15 | 9.x |
| 14 | 8.x |

## Basic usage
Import the `ReactiveValidationModule`:

```ts
import { ReactiveValidationModule } from 'angular-reactive-validation';

@NgModule({
imports: [
...,
ReactiveValidationModule
]
})
export class AppModule { }
```

Declare your validation with messages:

```ts
import { Validators } from 'angular-reactive-validation';

...

form = this.fb.group({
name: this.fb.group({
firstName: ['', [Validators.required('A first name is required'),
Validators.minLength(1, minLength => `The minimum length is ${minLength}`),
Validators.maxLength(50, maxLength => `Maximum length is ${maxLength}`)]],
middleName: ['', [Validators.maxLength(50, maxLength => `Maximum length is ${maxLength}`)]],
lastName: ['', [Validators.required('A last name is required'),
Validators.maxLength(50, maxLength => `Maximum length is ${maxLength}`)]]
}),
age: [null, [
Validators.required('An age is required'),
Validators.min(0, 'You can\'t be less than zero years old.'),
Validators.max(150, max => `Can't be more than ${max}`)
]]
});
```

See [Advanced validation declaration](#advanced-validation-declaration) for other ways to declare your validation.

Add the component that will display the messages to your HTML:

```html

```

Make changes to the styling of the validation messages when needed by using the `invalid-feedback` class. E.g.:

```scss
.invalid-feedback {
width: 100%;
margin-top: .25rem;
font-size: 80%;
color: red;
}
```

## Advanced validation declaration

The library supports specifying validators in a number of ways:

With a static message:

```ts
Validators.minLength(1, 'The minimum length is not reached.')
```

With a dynamic message, which is passed the validation value:

```ts
Validators.minLength(1, minLength => `The minimum length is ${minLength}.`)
```

With a dynamic validation value:

```ts
Validators.minLength(() => this.getMinimumLength(), 'The minimum length is not reached.')
```

Or combining the two options above:

```ts
Validators.minLength(() => this.getMinimumLength(), minLength => `The minimum length is ${minLength}.`)
```

## Changing when validation messages are displayed

By default validation messages are displayed when the associated control is touched, or when the form has been submitted while the `arv-validation-messages` component was instantiated (meaning any hidden elements would not show their validation until a resubmit).

This implementation can be overridden by changing the module import as follows:

```ts
import { ReactiveValidationModule } from 'angular-reactive-validation';

@NgModule({
imports: [
...,
ReactiveValidationModule.forRoot({
displayValidationMessageWhen: (control, formSubmitted) => {
return true; // Replace with your implementation.
}
})
]
})
export class AppModule { }
```

Note that `formSubmitted` can be undefined when it's not known if the form is submitted, due to the form tag missing a formGroup attribute.

## Declaring your own validator functions

Angular provides a limited set of validator functions. To declare your own validator functions _and_ combine it with this library use the `ValidatorDeclaration` class. It supports declaring validators with zero, one or two arguments.

**Note** that if your validator doesn't return an object as the inner error result, but e.g. a `boolean` such as in the examples below, then this will be replaced by an object that can hold the validation message. Thus, in the first example below `{ 'hasvalue': true }` becomes `{ 'hasvalue': { 'message': 'validation message' } }`.

```ts
const hasValueValidator = ValidatorDeclaration.wrapNoArgumentValidator(control => {
return !!control.value ? null : { 'hasvalue': true };
}, 'hasvalue');

const formControl = new FormControl('', hasValueValidator('error message to show'));
```

```ts
const minimumValueValidator = ValidatorDeclaration.wrapSingleArgumentValidator((min: number) => {
return function(control: AbstractControl): ValidationErrors {
return control.value >= min ? null : { 'min': true };
};
}, 'min');

const formControl = new FormControl('', minimumValueValidator(5, 'error message to show'));
```

```ts
const betweenValueValidator = ValidatorDeclaration.wrapTwoArgumentValidator((min: number, max: number) => {
return function(control: AbstractControl): ValidationErrors {
return control.value >= min && control.value <= max ? null : { 'between': true };
};
}, 'between');

const formControl = new FormControl('', betweenValueValidator(5, 10, 'error message to show'));
```

Wrapping validator functions provided by other packages is also very simple:

```ts
const minValidator = ValidatorDeclaration.wrapSingleArgumentValidator(AngularValidators.min, 'min')
```

## Edge use cases

### Handling custom HTML validation messages

Though not the purpose of this library. There might be times when you want to declare a validation message within your HTML, because it requires some custom formatting. Therefore, all the `Validators` can also be used without declaring a message:

```ts
Validators.minLength(() => this.getMinimumLength())
```

And the following HTML can be used:

```html


Your custom validation message HTML for the minimum value validation.

```

If the `arv-validation-messages`'s `for` attribute specifies multiple controls, be sure to declare the `for` attribute on the `arv-validation-message` element as well:

```html


Your custom validation message HTML for the required validation.


Your custom validation message HTML for the minlength validation.

```

Note that unlike the default Angular validation, parameterless functions need to be called to work properly:

```ts
Validators.required()
Validators.requiredTrue()
Validators.email()
```

### Using arv-validation-messages when not using `[formGroup]` or `formGroupName` attributes

Supplying FormControl instances instead of names is also supported:

```html


...

```