diff --git a/packages/forms/src/validators.ts b/packages/forms/src/validators.ts index bf432271a21a9..d871f0daa7bf3 100644 --- a/packages/forms/src/validators.ts +++ b/packages/forms/src/validators.ts @@ -18,37 +18,39 @@ function isEmptyInputValue(value: any): boolean { } /** - * Providers for validators to be used for `FormControl`s in a form. + * @description + * An `InjectionToken` for registering additional synchronous validators used with `AbstractControl`s. * - * Provide this using `multi: true` to add validators. - * - * ### Example + * @see `NG_ASYNC_VALIDATORS` + * + * @usageNotes + * + * ### Providing a custom validator + * + * The following example registers a custom validator directive. Adding the validator to the + * existing collection of validators requires the `multi: true` option. * * ```typescript * @Directive({ - * selector: '[custom-validator]', + * selector: '[customValidator]', * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}] * }) * class CustomValidatorDirective implements Validator { * validate(control: AbstractControl): ValidationErrors | null { - * return {"custom": true}; + * return { 'custom': true }; * } * } * ``` * - * */ export const NG_VALIDATORS = new InjectionToken>('NgValidators'); /** - * Providers for asynchronous validators to be used for `FormControl`s - * in a form. - * - * Provide this using `multi: true` to add validators. - * - * See `NG_VALIDATORS` for more details. - * + * @description + * An `InjectionToken` for registering additional asynchronous validators used with `AbstractControl`s. * + * @see `NG_VALIDATORS` + * */ export const NG_ASYNC_VALIDATORS = new InjectionToken>('NgAsyncValidators'); @@ -57,24 +59,34 @@ const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; /** - * Provides a set of validators used by form controls. + * @description + * Provides a set of built-in validators that can be used by form controls. * * A validator is a function that processes a `FormControl` or collection of - * controls and returns a map of errors. A null map means that validation has passed. - * - * ### Example - * - * ```typescript - * var loginControl = new FormControl("", Validators.required) - * ``` - * + * controls and returns an error map or null. A null map means that validation has passed. + * + * @see [Form Validation](/guide/form-validation) * */ export class Validators { /** - * Validator that requires controls to have a value greater than a number. - *`min()` exists only as a function, not as a directive. For example, - * `control = new FormControl('', Validators.min(3));`. + * @description + * Validator that requires the control's value to be greater than or equal to the provided number. + * The validator exists only as a function and not as a directive. + * + * @usageNotes + * + * ### Validate against a minimum of 3 + * + * ```typescript + * const control = new FormControl(2, Validators.min(3)); + * + * console.log(control.errors); // {min: {min: 3, actual: 2}} + * ``` + * + * @returns A validator function that returns an error map with the + * `min` property if the validation check fails, otherwise `null`. + * */ static min(min: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { @@ -89,9 +101,23 @@ export class Validators { } /** - * Validator that requires controls to have a value less than a number. - * `max()` exists only as a function, not as a directive. For example, - * `control = new FormControl('', Validators.max(15));`. + * @description + * Validator that requires the control's value to be less than or equal to the provided number. + * The validator exists only as a function and not as a directive. + * + * @usageNotes + * + * ### Validate against a maximum of 15 + * + * ```typescript + * const control = new FormControl(16, Validators.max(15)); + * + * console.log(control.errors); // {max: {max: 15, actual: 16}} + * ``` + * + * @returns A validator function that returns an error map with the + * `max` property if the validation check fails, otherwise `null`. + * */ static max(max: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { @@ -106,21 +132,66 @@ export class Validators { } /** - * Validator that requires controls to have a non-empty value. + * @description + * Validator that requires the control have a non-empty value. + * + * @usageNotes + * + * ### Validate that the field is non-empty + * + * ```typescript + * const control = new FormControl('', Validators.required); + * + * console.log(control.errors); // {required: true} + * ``` + * + * @returns An error map with the `required` property + * if the validation check fails, otherwise `null`. + * */ static required(control: AbstractControl): ValidationErrors|null { return isEmptyInputValue(control.value) ? {'required': true} : null; } /** - * Validator that requires control value to be true. + * @description + * Validator that requires the control's value be true. This validator is commonly + * used for required checkboxes. + * + * @usageNotes + * + * ### Validate that the field value is true + * + * ```typescript + * const control = new FormControl('', Validators.requiredTrue); + * + * console.log(control.errors); // {required: true} + * ``` + * + * @returns An error map that contains the `required` property + * set to `true` if the validation check fails, otherwise `null`. */ static requiredTrue(control: AbstractControl): ValidationErrors|null { return control.value === true ? null : {'required': true}; } /** - * Validator that performs email validation. + * @description + * Validator that requires the control's value pass an email validation test. + * + * @usageNotes + * + * ### Validate that the field matches a valid email pattern + * + * ```typescript + * const control = new FormControl('bad@', Validators.email); + * + * console.log(control.errors); // {email: true} + * ``` + * + * @returns An error map with the `email` property + * if the validation check fails, otherwise `null`. + * */ static email(control: AbstractControl): ValidationErrors|null { if (isEmptyInputValue(control.value)) { @@ -130,7 +201,27 @@ export class Validators { } /** - * Validator that requires controls to have a value of a minimum length. + * @description + * Validator that requires the length of the control's value to be greater than or equal + * to the provided minimum length. This validator is also provided by default if you use the + * the HTML5 `minlength` attribute. + * + * @usageNotes + * + * ### Validate that the field has a minimum of 3 characters + * + * ```typescript + * const control = new FormControl('ng', Validators.minLength(3)); + * + * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}} + * ``` + * + * ```html + * + * ``` + * + * @returns A validator function that returns an error map with the + * `minlength` if the validation check fails, otherwise `null`. */ static minLength(minLength: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { @@ -145,7 +236,27 @@ export class Validators { } /** - * Validator that requires controls to have a value of a maximum length. + * @description + * Validator that requires the length of the control's value to be less than or equal + * to the provided maximum length. This validator is also provided by default if you use the + * the HTML5 `maxlength` attribute. + * + * @usageNotes + * + * ### Validate that the field has maximum of 5 characters + * + * ```typescript + * const control = new FormControl('Angular', Validators.maxLength(5)); + * + * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}} + * ``` + * + * ```html + * + * ``` + * + * @returns A validator function that returns an error map with the + * `maxlength` property if the validation check fails, otherwise `null`. */ static maxLength(maxLength: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { @@ -157,7 +268,27 @@ export class Validators { } /** - * Validator that requires a control to match a regex to its value. + * @description + * Validator that requires the control's value to match a regex pattern. This validator is also + * provided + * by default if you use the HTML5 `pattern` attribute. + * + * @usageNotes + * + * ### Validate that the field only contains letters or spaces + * + * ```typescript + * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*')); + * + * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}} + * ``` + * + * ```html + * + * ``` + * + * @returns A validator function that returns an error map with the + * `pattern` property if the validation check fails, otherwise `null`. */ static pattern(pattern: string|RegExp): ValidatorFn { if (!pattern) return Validators.nullValidator; @@ -188,13 +319,18 @@ export class Validators { } /** - * No-op validator. + * @description + * Validator that performs no operation. */ static nullValidator(c: AbstractControl): ValidationErrors|null { return null; } /** + * @description * Compose multiple validators into a single function that returns the union - * of the individual error maps. + * of the individual error maps for the provided control. + * + * @returns A validator function that returns an error map with the + * merged error maps of the validators if the validation check fails, otherwise `null`. */ static compose(validators: null): null; static compose(validators: (ValidatorFn|null|undefined)[]): ValidatorFn|null; @@ -208,6 +344,14 @@ export class Validators { }; } + /** + * @description + * Compose multiple async validators into a single function that returns the union + * of the individual error objects for the provided control. + * + * @returns A validator function that returns an error map with the + * merged error objects of the async validators if the validation check fails, otherwise `null`. + */ static composeAsync(validators: (AsyncValidatorFn|null)[]): AsyncValidatorFn|null { if (!validators) return null; const presentValidators: AsyncValidatorFn[] = validators.filter(isPresent) as any;