ngx-valdemort
Version:
Simple, consistent validation error messages for your Angular forms
1 lines • 35.4 kB
Source Map (JSON)
{"version":3,"file":"ngx-valdemort.mjs","sources":["../../../projects/ngx-valdemort/src/lib/default-validation-errors.service.ts","../../../projects/ngx-valdemort/src/lib/validation-error.directive.ts","../../../projects/ngx-valdemort/src/lib/validation-fallback.directive.ts","../../../projects/ngx-valdemort/src/lib/default-validation-errors.directive.ts","../../../projects/ngx-valdemort/src/lib/valdemort-config.service.ts","../../../projects/ngx-valdemort/src/lib/validation-errors.component.ts","../../../projects/ngx-valdemort/src/lib/validation-errors.component.html","../../../projects/ngx-valdemort/src/lib/valdemort.module.ts","../../../projects/ngx-valdemort/src/public_api.ts","../../../projects/ngx-valdemort/src/ngx-valdemort.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\n\n/**\n * Service used by the default validation errors directive to store the default error template references. This\n * service is injected in the validation errors component which displays the appropriate templates and provides their context.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class DefaultValidationErrors {\n readonly directives = signal<ReadonlyArray<ValidationErrorDirective>>([]);\n readonly fallback = signal<ValidationFallbackDirective | undefined>(undefined);\n}\n","import { Directive, input, TemplateRef, inject } from '@angular/core';\n\n/**\n * The context of the ValidationErrorDirective\n */\ninterface ValidationErrorContext {\n /**\n * The label\n */\n $implicit: string | null;\n\n /**\n * The error\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any;\n}\n\n/**\n * Directive allowing to define the template for an error of a given type (using the `valError` input), using an ng-template.\n * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive.\n * See the documentation of these two for example usages.\n */\n@Directive({\n selector: 'ng-template[valError]'\n})\nexport class ValidationErrorDirective {\n readonly templateRef = inject<TemplateRef<ValidationErrorContext>>(TemplateRef);\n\n /**\n * The type of the error that the content of the template must display.\n */\n readonly type = input.required<string>({ alias: 'valError' });\n\n static ngTemplateContextGuard(_directive: ValidationErrorDirective, context: unknown): context is ValidationErrorContext {\n return true;\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\n\n/**\n * The context of the ValidationFallbackDirective\n */\ninterface ValidationFallbackContext {\n /**\n * The label\n */\n $implicit: string | null;\n\n /**\n * The error\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any;\n\n /**\n * The type of the error\n */\n type: string;\n}\n\n/**\n * Directive allowing to define a fallback template for an error of a type that is not handled by any validation error directive.\n * It's used inside the body of the validation errors component, or inside the body of the default validation errors directive.\n * See the documentation of these two for example usages.\n *\n * This is useful to handle forgotten errors instead of displaying no error at all, or to handle all or several error types in the same way,\n * for example by relying on the error key to choose an internationalized message.\n */\n@Directive({\n selector: 'ng-template[valFallback]'\n})\nexport class ValidationFallbackDirective {\n readonly templateRef = inject<TemplateRef<ValidationFallbackContext>>(TemplateRef);\n\n static ngTemplateContextGuard(_directive: ValidationFallbackDirective, context: unknown): context is ValidationFallbackContext {\n return true;\n }\n}\n","import { AfterContentInit, contentChild, contentChildren, Directive, inject } from '@angular/core';\nimport { DefaultValidationErrors } from './default-validation-errors.service';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\n\n/**\n * Directive allowing to register default templates for validation error messages. It's supposed to be used once,\n * typically in the root component. By using templates to do that, error messages can\n * - easily be i18ned\n * - easily use pipes\n * - easily use HTML\n * - easily be ordered\n *\n * Example usage:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\">This field is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">This field must be at most {{ error.max | number }}</ng-template>\n * </val-default-errors>\n * ```\n *\n * Example usage where a label is used to make the messages less generic:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template>\n * </val-default-errors>\n * ```\n *\n * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control\n * but are not handled by any of the specific error templates:\n * ```\n * <val-default-errors>\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>{{ label }} must be at most {{ error.max | number }}</ng-template>\n * <ng-template valFallback let-label let-type=\"type\" let-error=\"error\">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template>\n * </val-default-errors>\n * ```\n * Using the fallback can also be used to handle all the errors the same way, for example by using the error type as an i18n key\n * to display the appropriate error message.\n *\n * This directive stores the default template references in a service, that is then injected in the validation errors components\n * to be reused.\n */\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: 'val-default-errors'\n})\nexport class DefaultValidationErrorsDirective implements AfterContentInit {\n private defaultValidationErrors = inject(DefaultValidationErrors);\n\n /**\n * The list of validation error directives (i.e. <ng-template valError=\"...\">)\n * contained inside the directive element.\n */\n readonly errorDirectives = contentChildren(ValidationErrorDirective);\n\n /**\n * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the directive element.\n */\n readonly fallbackDirective = contentChild(ValidationFallbackDirective);\n\n ngAfterContentInit(): void {\n this.defaultValidationErrors.directives.set(this.errorDirectives());\n this.defaultValidationErrors.fallback.set(this.fallbackDirective());\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AbstractControl, FormGroupDirective, NgForm } from '@angular/forms';\n\n/**\n * The display mode of the validation errors. For a given control, either all the validation errors\n * are displayed, or only the first one.\n */\nexport enum DisplayMode {\n ALL,\n ONE\n}\n\n/**\n * The configuration service used by the validation errors component to apply common rules for all\n * form controls.\n *\n * To change its default behavior, you can either inject this service in your root module or component and mutate it,\n * or define your own implementation and provide it.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ValdemortConfig {\n /**\n * The display mode of the errors. The default value is ALL, meaning that all the errors existing on a control\n * (and which have an error template defined) are displayed.\n */\n displayMode = DisplayMode.ALL;\n\n /**\n * Specifies one or several CSS classes (separated by a white space) that are automatically added to the\n * validation errors element. This can be useful to reuse a standard CSS class of your CSS framework (like\n * .invalid-feedback in BootStrap), rather than styling the val-errors element itself.\n *\n * The default value is null (no class is added).\n */\n errorsClasses: string | null = null;\n\n /**\n * Specifies one or several CSS classes (separated by a white space) that are automatically added to the\n * each validation error message element. This can be useful to reuse a standard CSS class of your CSS framework\n * rather than styling the div element itself.\n *\n * The default value is null (no class is added).\n */\n errorClasses: string | null = null;\n\n /**\n * Specifies when error messages should be displayed. based on the state of the control itself (touched, dirty, etc.)\n * and on the state of the form directive containing it (if any). This function is only called if the control is invalid\n * in the first place: if it's valid, errors are never displayed.\n *\n * The default value of this function returns true if the control is touched, or if the form (if any) is submitted.\n */\n shouldDisplayErrors: (control: AbstractControl, form: NgForm | FormGroupDirective | undefined) => boolean = (\n control: AbstractControl,\n form: NgForm | FormGroupDirective | undefined\n ) => control.touched || (!!form && form.submitted);\n\n /**\n * Specifies if the library should throw an error when a control is not found.\n * For example, this can happen if a typo was made in the `controlName`.\n * If the check is enabled, then an error will be thrown in such a case.\n * Otherwise, the error is silently ignored.\n *\n * The default value of this function returns false, thus disabling the check.\n *\n * You can enable the check by giving it a function that returns true,\n * or you can enable it only in development for example with:\n * `config.shouldThrowOnMissingControl = () => !environment.production`\n */\n shouldThrowOnMissingControl: () => boolean = () => false;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n contentChildren,\n DoCheck,\n inject,\n input,\n signal,\n Signal\n} from '@angular/core';\nimport { AbstractControl, ControlContainer, FormArray, FormGroup, FormGroupDirective, NgForm, ValidationErrors } from '@angular/forms';\nimport { DisplayMode, ValdemortConfig } from './valdemort-config.service';\nimport { DefaultValidationErrors } from './default-validation-errors.service';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\nimport { NgTemplateOutlet } from '@angular/common';\n\ninterface FallbackError {\n type: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: any;\n}\n\ninterface ErrorsToDisplay {\n // The validation error directives to display\n errors: Array<ValidationErrorDirective>;\n\n // The fallback directive to use to display the fallback errors\n fallback: ValidationFallbackDirective | undefined;\n\n // the fallback errors to display (empty if there is no fallback directive)\n fallbackErrors: Array<FallbackError>;\n}\n\ntype ViewModel =\n | {\n shouldDisplayErrors: false;\n }\n | {\n shouldDisplayErrors: true;\n errorsToDisplay: ErrorsToDisplay;\n control: AbstractControl;\n };\n\nconst NO_ERRORS: ViewModel = {\n shouldDisplayErrors: false\n};\n\ninterface ValidationState {\n control: AbstractControl | null;\n errorsDisplayed: boolean | null;\n errors: ValidationErrors | null;\n}\n\nconst NO_VALIDATION_STATE: ValidationState = {\n control: null,\n errorsDisplayed: null,\n errors: null\n};\n\nfunction areValidationStatesEqual(previous: ValidationState, current: ValidationState): boolean {\n return previous.control === current.control && previous.errorsDisplayed === current.errorsDisplayed && previous.errors === current.errors;\n}\n\n/**\n * Component allowing to display validation error messages associated to a given form control, form group or form array.\n * The control is provided using the `control` input of the component. If it's used inside an enclosing form group or\n * form array, it can instead be provided using the `controlName` input of the component.\n *\n * Example usage where the control itself is being passed as input:\n * ```\n * <val-errors [control]=\"form.controls.birthDate\">\n * <ng-template valError=\"required\">The birth date is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">The max value for the birth date is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * Example usage where the control name is being passed as input:\n * ```\n * <val-errors controlName=\"birthDate\">\n * <ng-template valError=\"required\">The birth date is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\">The max value for the birth date is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * This component, if the control is invalid, displays its validation errors using the provided templates.\n * The templates, as shown in the above example, have access to the validation error itself.\n *\n * The label of the control can also be provided as input, and then used in the templates:\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"required\" let-label>{{ label }} is mandatory</ng-template>\n * <ng-template valError=\"max\" let-error=\"error\" let-label>The max value for {{ label }} is {{ error.max | number }}</ng-template>\n * </val-errors>\n * ```\n *\n * The component‘s behavior is configured globally by the Config service (see its documentation for more details). It can\n * - display the first error, or all the errors\n * - add CSS classes to its host `<val-errors>` element\n * - add CSS classes to each error message element being displayed\n * - choose when to display the errors (dirty, touched, touched and submitted, etc.)\n *\n * Global, default templates can be defined (and used by this component) using the default validation errors directive\n * (see its documentation for details). So, if the default error messages are defined and sufficient for a given control, all you\n * need is\n *\n * ```\n * <val-errors controlName=\"birthDate\"></val-errors>\n * ```\n *\n * or, if the default templates expect a label:\n *\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\"></val-errors>\n * ```\n *\n * If, however, you want to override one or several error messages by custom ones, you can do so by simply defining them inside the\n * component:\n *\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * </val-errors>\n * ```\n *\n * A fallback template can also be provided. This fallback template is used for all the errors that exist on the form control\n * but are not handled by any of the specific error templates:\n * ```\n * <val-errors controlName=\"birthDate\" label=\"the birth date\">\n * <ng-template valError=\"max\">You're too young, sorry</ng-template>\n * <ng-template valFallback let-label let-type=\"type\" let-error=\"error\">{{ label }} has an unhandled error of type {{ type }}: {{ error | json }}</ng-template>\n * </val-errors>\n * ```\n * Note that, the fallback template can also be defined in the default validation errors directive (see its documentation for details).\n * If a fallback template is defined inside `val-errors`, it overrides the default fallback.\n *\n * If an error is present on the control, but doesn't have any template, default template or fallback template defined for its type,\n * then it's not displayed. If the control is valid, or if none of the errors of the component has a matching template or default template,\n * then this component itself is hidden.\n */\n@Component({\n selector: 'val-errors',\n templateUrl: './validation-errors.component.html',\n host: {\n '[class]': 'errorsClasses',\n '[style.display]': `vm().shouldDisplayErrors ? '' : 'none'`\n },\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ValidationErrorsComponent implements DoCheck {\n /**\n * The FormControl, FormGroup or FormArray containing the validation errors.\n * If set, the controlName input is ignored\n */\n readonly control = input<AbstractControl | null>(null);\n\n /**\n * The name (or the index, in case it's contained in a FormArray) of the FormControl, FormGroup or FormArray containing the validation\n * errors.\n * Ignored if the control input is set, and only usable if the control to validate is part of a control container\n */\n readonly controlName = input<string | number | null>(null);\n\n /**\n * The label of the field, exposed to templates so they can use it in the error message.\n */\n readonly label = input<string | null>(null);\n\n /**\n * The list of validation error directives (i.e. <ng-template valError=\"...\">) contained inside the component element.\n */\n readonly errorDirectives = contentChildren(ValidationErrorDirective);\n\n /**\n * The validation fallback directive (i.e. <ng-template valFallback>) contained inside the component element.\n */\n readonly fallbackDirective = contentChild(ValidationFallbackDirective);\n\n /**\n * The Config service instance, defining the behavior of this component\n */\n private readonly config = inject(ValdemortConfig);\n readonly errorsClasses = this.config.errorsClasses || '';\n readonly errorClasses = this.config.errorClasses || '';\n\n private readonly validationState = signal<ValidationState>(NO_VALIDATION_STATE, { equal: areValidationStatesEqual });\n\n /**\n * The DefaultValidationErrors service instance, holding the default error templates,\n * optionally defined by using the default validation errors directive\n */\n private readonly defaultValidationErrors = inject(DefaultValidationErrors);\n\n /**\n * The control container, if it exists, as one of the 4 form group or form array directives that can \"wrap\" the control.\n * It's injected so that we can know if it exists and, if it does, if its form directive has been submitted or not:\n * the config service shouldDisplayErrors function can choose (and does by default) to use that information.\n */\n private readonly controlContainer = inject(ControlContainer, { optional: true });\n\n readonly vm: Signal<ViewModel> = computed(() => {\n const ctrl = this.validationState().control;\n if (this.shouldDisplayErrors(ctrl)) {\n const errorsToDisplay = this.findErrorsToDisplay(ctrl);\n return {\n shouldDisplayErrors: true,\n control: ctrl,\n errorsToDisplay\n };\n } else {\n return NO_ERRORS;\n }\n });\n\n ngDoCheck(): void {\n const ctrl = this.findActualControl();\n if (ctrl) {\n const formDirective = this.controlContainer?.formDirective as NgForm | FormGroupDirective | undefined;\n const errorsDisplayed = this.config.shouldDisplayErrors(ctrl, formDirective);\n this.validationState.set({\n control: ctrl,\n errorsDisplayed,\n errors: ctrl.errors\n });\n } else {\n this.validationState.set(NO_VALIDATION_STATE);\n }\n }\n\n private shouldDisplayErrors(ctrl: AbstractControl | null): ctrl is AbstractControl {\n if (!ctrl || !ctrl.invalid || !this.hasDisplayableError(ctrl)) {\n return false;\n }\n const form = this.controlContainer && (this.controlContainer.formDirective as NgForm | FormGroupDirective);\n return this.config.shouldDisplayErrors(ctrl, form ?? undefined);\n }\n\n private findErrorsToDisplay(ctrl: AbstractControl): ErrorsToDisplay {\n const mergedDirectives: Array<ValidationErrorDirective> = [];\n const fallbackErrors: Array<FallbackError> = [];\n const alreadyMetTypes = new Set<string>();\n const shouldContinue = () =>\n this.config.displayMode === DisplayMode.ALL || (mergedDirectives.length === 0 && fallbackErrors.length === 0);\n const defaultValidationErrorDirectives = this.defaultValidationErrors.directives();\n for (let i = 0; i < defaultValidationErrorDirectives.length && shouldContinue(); i++) {\n const defaultDirective = defaultValidationErrorDirectives[i];\n if (ctrl.hasError(defaultDirective.type())) {\n const customDirectiveOfSameType = this.errorDirectives().find(dir => dir.type() === defaultDirective.type());\n mergedDirectives.push(customDirectiveOfSameType || defaultDirective);\n }\n alreadyMetTypes.add(defaultDirective.type());\n }\n\n if (shouldContinue()) {\n const customDirectives = this.errorDirectives();\n for (let i = 0; i < customDirectives.length && shouldContinue(); i++) {\n const customDirective = customDirectives[i];\n if (ctrl.hasError(customDirective.type()) && !alreadyMetTypes.has(customDirective.type())) {\n mergedDirectives.push(customDirective);\n }\n alreadyMetTypes.add(customDirective.type());\n }\n }\n\n if (shouldContinue() && (this.fallbackDirective() || this.defaultValidationErrors.fallback())) {\n const allErrors = Object.entries(ctrl.errors ?? []);\n for (let i = 0; i < allErrors.length && shouldContinue(); i++) {\n const [type, value] = allErrors[i];\n if (!alreadyMetTypes.has(type)) {\n fallbackErrors.push({ type, value });\n }\n }\n }\n\n return {\n errors: mergedDirectives,\n fallback: this.fallbackDirective() ?? this.defaultValidationErrors.fallback(),\n fallbackErrors\n };\n }\n\n private findActualControl(): AbstractControl | null {\n const ctrl = this.control();\n const ctrlName = this.controlName();\n if (ctrl) {\n return ctrl;\n } else if (ctrlName != null && (this.controlContainer?.control as FormArray | FormGroup)?.controls) {\n // whether the control is a FormGroup or a FormArray, we must use .control[ctrlName] to get it\n const control = (this.controlContainer?.control as FormArray).controls[ctrlName as number];\n if (this.config.shouldThrowOnMissingControl()) {\n // if the control is null, then there are two cases:\n // - we are in a template driven form, and the controls might not be initialized yet\n // - there was an error in the control name. If so, let's throw an error to help developers\n // to avoid false positive in template driven forms, we check if the controls are initialized\n // by checking if the `controls` object or array has any element\n if (!control && Object.keys((this.controlContainer?.control as FormArray)?.controls).length > 0) {\n throw new Error(`ngx-valdemort: no control found for controlName: '${ctrlName}'.`);\n }\n }\n return control;\n }\n return null;\n }\n\n private hasDisplayableError(ctrl: AbstractControl) {\n return (\n ctrl.errors &&\n (this.fallbackDirective() ||\n this.defaultValidationErrors.fallback() ||\n Object.keys(ctrl.errors).some(\n type =>\n this.defaultValidationErrors.directives().some(dir => dir.type() === type) ||\n this.errorDirectives().some(dir => dir.type() === type)\n ))\n );\n }\n}\n","@if (vm(); as vm) {\n @if (vm.shouldDisplayErrors) {\n @for (errorDirective of vm.errorsToDisplay.errors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n errorDirective!.templateRef;\n context: {\n $implicit: label(),\n error: vm.control.errors![errorDirective.type()]\n }\n \"\n />\n </div>\n }\n @for (error of vm.errorsToDisplay.fallbackErrors; track $index) {\n <div [class]=\"errorClasses\">\n <ng-container\n *ngTemplateOutlet=\"\n vm.errorsToDisplay.fallback!.templateRef;\n context: {\n $implicit: label(),\n type: error.type,\n error: error.value\n }\n \"\n />\n </div>\n }\n }\n}\n","import { NgModule } from '@angular/core';\nimport { ValidationErrorsComponent } from './validation-errors.component';\nimport { DefaultValidationErrorsDirective } from './default-validation-errors.directive';\nimport { ValidationErrorDirective } from './validation-error.directive';\nimport { ValidationFallbackDirective } from './validation-fallback.directive';\n\n@NgModule({\n imports: [ValidationErrorsComponent, ValidationErrorDirective, ValidationFallbackDirective, DefaultValidationErrorsDirective],\n exports: [ValidationErrorsComponent, ValidationErrorDirective, ValidationFallbackDirective, DefaultValidationErrorsDirective]\n})\nexport class ValdemortModule {}\n","/*\n * Public API Surface of ngx-validation-errors\n */\n\nexport * from './lib/default-validation-errors.directive';\nexport * from './lib/validation-error.directive';\nexport * from './lib/validation-fallback.directive';\nexport * from './lib/validation-errors.component';\nexport * from './lib/valdemort-config.service';\nexport * from './lib/valdemort.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}