UNPKG

aspnet-client-validation

Version:

Enables ASP.NET MVC client-side validation, without jQuery!

395 lines (394 loc) 15.5 kB
/** * A simple IDictionary<string, string> */ export interface StringKeyValuePair { [key: string]: string; } /** * A simple logging interface that mirrors the Console object. */ export interface Logger { log(message: string, ...args: any[]): void; warn(message: string, ...args: any[]): void; } /** * An `HTMLElement` that can be validated (`input`, `select`, `textarea`). */ export type ValidatableElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; /** * Checks if `element` is validatable (`input`, `select`, `textarea`). * @param element The element to check. * @returns `true` if validatable, otherwise `false`. */ export declare const isValidatable: (element: Node) => element is ValidatableElement; /** * Parameters passed into validation providers from the element attributes. * error property is read from data-val-[Provider Name] attribute. * params property is populated from data-val-[Provider Name]-[Parameter Name] attributes. */ export interface ValidationDirectiveBindings { error: string; params: StringKeyValuePair; } /** * A key-value pair describing what validations to enforce to an input element, with respective parameters. */ export type ValidationDirective = { [key: string]: ValidationDirectiveBindings; }; /** * Validation plugin signature with multitype return. * Boolean return signifies the validation result, which uses the default validation error message read from the element attribute. * String return signifies failed validation, which then will be used as the validation error message. * Promise return signifies asynchronous plugin behavior, with same behavior as Boolean or String. */ export type ValidationProvider = (value: string, element: ValidatableElement, params: StringKeyValuePair) => boolean | string | Promise<boolean | string>; /** * Callback to receive the result of validating a form. */ export type ValidatedCallback = (success: boolean) => void; /** * Contains default implementations for ASP.NET Core MVC validation attributes. */ export declare class MvcValidationProviders { /** * Validates whether the input has a value. */ required: ValidationProvider; /** * Validates whether the input value satisfies the length contstraint. */ stringLength: ValidationProvider; /** * Validates whether the input value is equal to another input value. */ compare: ValidationProvider; /** * Validates whether the input value is a number within a given range. */ range: ValidationProvider; /** * Validates whether the input value satisfies a regular expression pattern. */ regex: ValidationProvider; /** * Validates whether the input value is an email in accordance to RFC822 specification, with a top level domain. */ email: ValidationProvider; /** * Validates whether the input value is a credit card number, with Luhn's Algorithm. */ creditcard: ValidationProvider; /** * Validates whether the input value is a URL. */ url: ValidationProvider; /** * Validates whether the input value is a phone number. */ phone: ValidationProvider; /** * Asynchronously validates the input value to a JSON GET API endpoint. */ remote: ValidationProvider; } /** * Configuration for @type {ValidationService}. */ export interface ValidationServiceOptions { watch: boolean; root: ParentNode; addNoValidate: boolean; } /** * Responsible for managing the DOM elements and running the validation providers. */ export declare class ValidationService { /** * A key-value collection of loaded validation plugins. */ private providers; /** * A key-value collection of form UIDs and their <span> elements for displaying validation messages for an input (by DOM name). */ private messageFor; /** * A list of managed elements, each having a randomly assigned unique identifier (UID). */ private elementUIDs; /** * A key-value collection of UID to Element for quick lookup. */ private elementByUID; /** * A key-value collection of input UIDs for a <form> UID. */ private formInputs; /** * A key-value map for input UID to its validator factory. */ private validators; /** * A key-value map for form UID to its trigger element (submit event for <form>). */ private formEvents; /** * A key-value map for element UID to its trigger element (input event for <textarea> and <input>, change event for <select>). */ private inputEvents; /** * A key-value map of input UID to its validation error message. */ private summary; /** * A serialized representation of the validation error message summary rendered to the user. */ private renderedSummaryJSON; /** * In milliseconds, the rate of fire of the input validation. */ debounce: number; /** * Allow hidden fields validation */ allowHiddenFields: boolean; private logger; observer?: MutationObserver; constructor(logger?: Logger); /** * Registers a new validation plugin of the given name, if not registered yet. * Registered plugin validates inputs with data-val-[name] attribute, used as error message. * @param name * @param callback */ addProvider(name: string, callback: ValidationProvider): void; /** * Registers the default providers for enabling ASP.NET Core MVC client-side validation. */ private addMvcProviders; /** * Scans `root` for all validation message <span> generated by ASP.NET Core MVC, then calls `cb` for each. * @param root The root node to scan * @param cb The callback to invoke with each form and span */ private scanMessages; private pushValidationMessageSpan; private removeValidationMessageSpan; /** * Given attribute map for an HTML input, returns the validation directives to be executed. * @param attributes */ parseDirectives(attributes: NamedNodeMap): ValidationDirective; /** * Returns an RFC4122 version 4 compliant GUID. */ private guid4; /** * Gets a UID for an DOM element. * @param node */ private getElementUID; /** * Returns a Promise that returns validation result for each and every inputs within the form. * @param formUID */ private getFormValidationTask; private getMessageFor; /** * Fires off validation for elements within the provided form and then calls the callback * @param form The form to validate. * @param callback Receives true or false indicating validity after all validation is complete. * @returns Promise that resolves to true or false indicating validity after all validation is complete. */ validateForm: (form: HTMLFormElement, callback?: ValidatedCallback) => Promise<boolean>; /** * Fires off validation for the provided element and then calls the callback * @param field The element to validate. * @param callback Receives true or false indicating validity after all validation is complete. * @returns Promise that resolves to true or false indicating validity after all validation is complete */ validateField: (field: ValidatableElement, callback?: ValidatedCallback) => Promise<boolean>; /** * Called before validating form submit events. * Default calls `preventDefault()` and `stopImmediatePropagation()`. * @param submitEvent The `SubmitEvent`. */ preValidate: (submitEvent: SubmitEvent) => void; /** * Handler for validated form submit events. * Default calls `submitValidForm(form, submitEvent)` on success * and `focusFirstInvalid(form)` on failure. * @param form The form that has been validated. * @param success The validation result. * @param submitEvent The `SubmitEvent`. */ handleValidated: (form: HTMLFormElement, success: boolean, submitEvent?: SubmitEvent) => void; /** * Dispatches a new `SubmitEvent` on the provided form, * then calls `form.submit()` unless `submitEvent` is cancelable * and `preventDefault()` was called by a handler that received the new event. * * This is equivalent to `form.requestSubmit()`, but more flexible. * @param form The validated form to submit * @param submitEvent The `SubmitEvent`. */ submitValidForm: (form: HTMLFormElement, submitEvent: SubmitEvent) => void; /** * Focuses the first invalid element within the provided form * @param form */ focusFirstInvalid: (form: HTMLFormElement) => void; /** * Returns true if the provided form is currently valid. * The form will be validated unless prevalidate is set to false. * @param form The form to validate. * @param prevalidate Whether the form should be validated before returning. * @param callback A callback that receives true or false indicating validity after all validation is complete. Ignored if prevalidate is false. * @returns The current state of the form. May be inaccurate if any validation is asynchronous (e.g. remote); consider using `callback` instead. */ isValid: (form: HTMLFormElement, prevalidate?: boolean, callback?: ValidatedCallback) => boolean; /** * Returns true if the provided field is currently valid. * The field will be validated unless prevalidate is set to false. * @param field The field to validate. * @param prevalidate Whether the field should be validated before returning. * @param callback A callback that receives true or false indicating validity after all validation is complete. Ignored if prevalidate is false. * @returns The current state of the field. May be inaccurate if any validation is asynchronous (e.g. remote); consider using `callback` instead. */ isFieldValid: (field: ValidatableElement, prevalidate?: boolean, callback?: ValidatedCallback) => boolean; /** * Returns true if the event triggering the form submission indicates we should validate the form. * @param e */ private shouldValidate; /** * Tracks a <form> element as parent of an input UID. When the form is submitted, attempts to validate the said input asynchronously. * @param form * @param inputUID */ private trackFormInput; reset(input: HTMLElement): void; private resetField; private untrackFormInput; /** * Adds an input element to be managed and validated by the service. * Triggers a debounced live validation when input value changes. * @param input */ addInput(input: ValidatableElement): void; removeInput(input: ValidatableElement): void; /** * Scans `root` for input elements to be validated, then calls `cb` for each. * @param root The root node to scan * @param cb The callback to invoke with each input */ private scanInputs; /** * Returns a <ul> element as a validation errors summary. */ createSummaryDOM(): HTMLUListElement; /** * Displays validation summary to ASP.NET Core MVC designated elements, when it actually gets updated. */ private renderSummary; /** * Adds an error message to an input element, which also updates the validation message elements and validation summary elements. * @param input * @param message */ addError(input: ValidatableElement, message: string): void; /** * Removes an error message from an input element, which also updates the validation message elements and validation summary elements. * @param input */ removeError(input: ValidatableElement): void; /** * Returns a validation Promise factory for an input element, using given validation directives. * @param input * @param directives */ createValidator(input: ValidatableElement, directives: ValidationDirective): () => Promise<boolean>; /** * Checks if the provided input is hidden from the browser * @param input * @returns */ private isHidden; /** * Checks if the provided input is disabled * @param input * @returns */ private isDisabled; /** * Adds addClass and removes removeClass * @param element Element to modify * @param addClass Class to add * @param removeClass Class to remove */ private swapClasses; /** * Options for this instance of @type {ValidationService}. */ private options; /** * Load default validation providers and scans the entire document when ready. * @param options.watch If set to true, a MutationObserver will be used to continuously watch for new elements that provide validation directives. * @param options.addNoValidate If set to true (the default), a novalidate attribute will be added to the containing form in validate elements. */ bootstrap(options?: Partial<ValidationServiceOptions>): void; /** * Scans the root element for any validation directives and attaches behavior to them. * @param root The root node to scan; if not provided, `options.root` (default: `document.body`) will be scanned */ scan(root?: ParentNode): void; /** * Scans the root element for any validation directives and removes behavior from them. * @param root The root node to scan; if not provided, `options.root` (default: `document.body`) will be scanned */ remove(root?: ParentNode): void; /** * Watches the provided root element for mutations, and scans for new validation directives to attach behavior. * @param root The root node to watch; if not provided, `options.root` (default: `document.body`) will be watched */ watch(root?: ParentNode): void; private observed; /** * Highlights invalid element by adding errorClass CSS class and removing validClass CSS class * @param input Element to modify * @param errorClass Class to add * @param validClass Class to remove */ highlight(input: ValidatableElement, errorClass: string, validClass: string): void; /** * Unhighlight valid element by removing errorClass CSS class and adding validClass CSS class * @param input Element to modify * @param errorClass Class to remove * @param validClass Class to add */ unhighlight(input: ValidatableElement, errorClass: string, validClass: string): void; /** * Override CSS class name for input validation error. Default: 'input-validation-error' */ ValidationInputCssClassName: string; /** * Override CSS class name for valid input validation. Default: 'input-validation-valid' */ ValidationInputValidCssClassName: string; /** * Override CSS class name for field validation error. Default: 'field-validation-error' */ ValidationMessageCssClassName: string; /** * Override CSS class name for valid field validation. Default: 'field-validation-valid' */ ValidationMessageValidCssClassName: string; /** * Override CSS class name for validation summary error. Default: 'validation-summary-errors' */ ValidationSummaryCssClassName: string; /** * Override CSS class name for valid validation summary. Default: 'validation-summary-valid' */ ValidationSummaryValidCssClassName: string; }