Useful JavaScript functions for manipulating and validating forms using HTML5 client-side form validation.

It could be used with libraries like React.js and Vue.js since they don’t have built-in features for form validation.

Different API used in this file are :

  • target.checkValidity(), target.validity.valid for checking if there are any errors and getting validityState object. The main difference is that checkValidity() will also fire an “invalid” event. If you just want to know whether the value is valid, use ValidityState.valid. But if you want to change the form state to invalid, use checkValidity().
  • validityState.valueMissing to check for required HTLM5 attribute.
  • typeMismatch, patternMismatch for HTML5 input types and pattern attribute (e.g. regex).
  • tooLong, tooShort, rangeUnderflow, rangeOverflow, stepMismatch, badInput respectively for maxlength, minlength, min, max, step attributes (step is for number type) and convert issues (browser, etc.).

Show error messages :

Before sharing the gist link, i would show how it’s possible to check if an input is in invalid state without getting the validityState object. This i very useful when you only and quickly want to show error messages for inputs. You can always use state object for last validation before posting a request.

For this you can bind an event listener to your <input> for the “invalid” event (or to <form>, or any other wrapper if you would avoid adding multiple event listeners) and react to that in your callback function by adding for example a css class. Note that this event is fired after check done on blur and you can lean more about it here.

Github gist :

export default class FormHelper {
/**
* Check input for validity using JavaScript/HTML5 client-side form validation
* Link : https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation
* @param {object} target – e.g. JavaScript event.target or selected HTML element object
* @returns {string []} – Errors list
*/
static inputValidation = (target) => {
if (!target) return null;
let errors = [];
if (target.checkValidity() || target.validity.valid) {
return errors;
}
const validityState = target.validity;
/*required*/
if (validityState.valueMissing) errors.push("Required field");
/*type, pattern*/
if (validityState.typeMismatch || validityState.patternMismatch)
errors.push("Invalid format");
/*maxlength, minlength, min, max, step (number type), convert*/
if (
validityState.tooLong ||
validityState.tooShort ||
validityState.rangeUnderflow ||
validityState.rangeOverflow ||
validityState.stepMismatch ||
validityState.badInput
)
errors.push("Invalid value");
/*custom*/
if (validityState.customError)
errors.push("Custom error was added using setCustomValidity");
return errors;
};
/**
* Get input by its name and check it for validity, useful for named field (React.js, Angular)
* @param {string} name – Value of name attribute of the input
* @returns {string []} – Errors list
*/
static isValidInput = (name) => {
if (!name) return null;
const target = document.querySelector(`input[name=${name}]`);
const inputErrors = this.inputValidation(target);
return !inputErrors || inputErrors.length === 0;
};
/**
* Get and check a list of inputs
* @param {string} names – Input names list
* @returns {string []} – Errors list
*/
static isValidInputs = (names) => {
if (!names || names.length === 0) return null;
for (let i = 0; i < names.length; i++) {
if (!this.isValidInput(names[i])) return false;
}
return true;
};
/**
* Generate an object from HTML form
* @param {object} form – Form object (e.g. document.querySelector("form"));
* @returns {object} – Form values
*/
static objectifyForm = (form) => {
/* Can use 'new FormData(form)' */
const objectForm = {};
const elements = form.elements;
for (let i = 0; i < elements.length; i++) {
objectForm[elements[i].name] = elements[i].value;
}
return objectForm;
};
}
view raw form_helper.js hosted with ❤ by GitHub