Skip to content

querkmachine/vanilla-validation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vanilla Validation

Vanilla Validation is a little "set and forget" JavaScript class that leverages the ValidityState API for customised client-side validation. It aims to be accessible and have no external dependencies, and it's a little bit opinionated (hopefully, in a good way).

This is my first npm-published FOSS library. Patience with any publishing mistakes or little weirdsies is appreciated, as is any constructive feedback.

Install

// npm
npm install @querkmachine/vanilla-validation

// Yarn
yarn add @querkmachine/vanilla-validation

Usage

In the browser:

<script src="path/to/validate.min.js"></script>

<script>
  const formElement = document.getElementById("form"); // or whatever other method you choose
  new Validate(formElement [, options]);
</script>

With CommonJS/UMD:

const Validate = require("@querkmachine/vanilla-validation");

const formElement = document.getElementById("form"); // or whatever other method you choose
new Validate(formElement [, options]);

With ESM:

import Validate from "@querkmachine/vanilla-validation";

const formElement = document.getElementById("form"); // or whatever other method you choose
new Validate(formElement [, options]);
  • formElement doesn't have to use getElementById, this can be any means you choose of getting a single <form> element. Use querySelector, loop through every form on the page, do something else entirely. How you do it is up to you.
  • options is an optional object containing configuration options.

Default configuration

{
  showInlineErrors: true,
  showErrorSummary: true,
  disableButtonsOnSubmit: true,
  submitButtonSelector: '[type="submit"], [type="image"]',
  errorSummaryClass: "error-message-summary",
  inlineErrorClass: "error-message",
  inputsDeferToFieldsets: [],
  i18n: {
    valRequired: "This field is required.",
    valType: "Value doesn't match expected type.",
    valTypeColor: "Value should be a valid hexidecimal code (for example, #786999).",
    valTypeEmail: "Value should be a valid email address (for example, hello@example.com).",
    valTypeNumber: "Value should be a valid number.",
    valTypeTel: "Value should be a valid telephone number.",
    valTypeURL: "Value should be a valid web address, including the protocol (for example, https://example.com).",
    valPattern: "Value doesn't match expected format.",
    valMaxlength: "Value cannot be longer than {1} characters. Currently it's {2} characters.",
    valMinlength: "Value cannot be shorter than {1} characters. Currently it's {2} characters.",
    valMax: "Value must be {1} or less.",
    valMin: "Value must be {1} or more.",
    valStep: "Value must be a multiple of {1}.",
  }
}

Configuration options

  • showInlineErrors (boolean) Shows error messages above the respective fields. For radio button groups and inputs defined in inputsDeferToFieldsets, the error will be shown below the fieldset legend. Default: true.
  • showErrorSummary (boolean) Shows a summary of error messages at the top of the form, with links to each invalid input. Default: true.
  • disableButtonsOnSubmit (boolean) Disables all type="submit" buttons in the form if the form successfully passes validation—and applies aria-busy="true"—to prevent multiple clicks sending more than one request. Default: true.
  • inputsDeferToFieldsets (array) A list of input ids. These IDs will defer to their parent fieldset when gathering error labelling and displaying inline error messaging. Empty by default, however note that radio buttons ALWAYS defer to their fieldsets.
  • inlineErrorClass (string) Classes to apply to inline errors. Default: "error-message".
  • errorSummaryClass (string) Classes to apply to the error summary container. Default: "error-message-summary".
  • i18n (object) Object to override the default error messaging, described right now.

Customising error messages

Global error messages are defined via the i18n configuration option. Individual inputs can display custom error messages, which are defined in HTML using data-* attributes.

Some error types allow for the interpolation of additional details within the error message.

ValidityState type HTML attribute i18n JS config data-* config Notes
valueMissing required valRequired data-val-required Expected a value.
typeMismatch type valType data-val-type Value does not conform to the input's type. This is a generic message used when a more specific mismatch doesn't exist. {1} is interpolated to the input's type attribute.
typeMismatch type="color" valTypeColor Expected a hexidecimal color value.
typeMismatch type="date" valTypeDate Expected an ISO 8601 date value (YYYY-MM-DD).
typeMismatch type="email" valTypeEmail Expected an RFC 822 formatted email address.
typeMismatch type="number" valTypeNumber Expected a numerical value.
typeMismatch type="tel" valTypeTel Expected a phone number. In practice, browsers rarely validate this type as there are too many possible phone number formats to practically validate against.
typeMismatch type="url" valTypeURL Expected a URL (including protocol).
tooLong maxlength valMaxlength data-val-maxlength The value provided is longer than the permitted maximum. {1} is interpolated to the input's maxlength attribute value, {2} is the current value's length.
tooShort minlength valMinlength data-val-minlength The value provided is shorter than the permitted minimum. {1} is interpolated to the input's minlength attribute value, {2} is the current value's length.
rangeOverflow max valMax data-val-max The value is higher than the permitted maximum. {1} is interpolated to the input's max attribute value, {2} is the current value.
rangeUnderflow min valMin data-val-min The value is lower than the permitted minimum. {1} is interpolated to the input's min attribute value, {2} is the current value.
stepMismatch step valStep data-val-step The value is not a multiple of the step (plus min, if present). {1} is interpolated to be the value of the input's step attribute.

If an input has a custom error message currently set via setCustomValidity, it will be displayed if none of the above validations are met.

Opinions

Vanilla Validation is opinionated. That means it makes some (hopefully sensible) assumptions about how your HTML is written and how you want validation to behave.

  • All validations are activated and configured via HTML attributes.
  • A user's browser must support the specific validation type for it to work. See the table above for CanIUse links for browser support. (And you should be implementing the same validation on the server-side anyway!)
  • Inline error messages are always displayed above the input, on the basis that it constitutes the most logical and accessibility-focused reading order (input label asks for a value -> error indicates problem with value -> input field to correct value).
  • Radio buttons are always validated in groups, and groups of radio button are expected to always be inside of a fieldset. This is because many validation functions for radio buttons work on a group level, and groups of inputs semantically belong in fieldsets.
  • All inputs (be they text, checkbox, select, etc.) that accept validation should have an id attribute. This ID is used to link error messaging to the input.
  • If a form fails validation, Vanilla Validation will always jump to either the first invalid input or to the error summary (if enabled by showErrorSummary).
  • Validation is only performed on form submission, not on input blur or when the value is changed.
  • If the submit button a user clicks has a name attribute, the name and value will be automatically copied to a hidden input to avoid this information being lost if the button is disabled by disableButtonsOnSubmit (this is carried out even if disableButtonsOnSubmit is set to false).
  • If a <form> has the novalidate attribute at the point that Vanilla Validation is initialised, Vanilla Validation will not run.