Treehouse From Validator Documentation

ThFormValidator is a light, extensible, dependency-free plugin for validating forms. It has some basic validations built in and allows you to add your own.

Usage

Getting Started

Include the script on your page:

<script src="https://cdn.treehouseinternetgroup.com/cms_core/assets/js/th_form_validator.js"></script>

The plugin can be instantiated using the new keyword: new ThFormValidator(<form id>, {<options object>}).

Pass the form’s ID as the first parameter:

<script>
const validator = new ThFormValidator("contact_form");
</script>

Options can be added as an object:

<script>
const validator = new ThFormValidator("contact_form", {disableSubmit: true});
</script>

When using built-in and custom validators, add the validator name to the end of data-validate- attribute and pass any parameters as the value:

<!-- Validate a UK phone number -->
<input id="Phone" name="phone_number" type="text" data-validate-phone="gb">

<!-- Validate a US phone number (us is set by default - no opt attribute required) -->
<input id="Phone" name="phone_number" type="text" data-validate-phone">

Available Options

Option Type Default Description
disableSubmit Boolean false Prevents adding a submit event listener on init. Allows you to define the submit event yourself.
validateOnBlur Boolean true Whether to validate a field when it looses focus.
errorMessageClass String ‘error’ The class name added to error message elements.
errorMessageTag String ‘label’ The tag used for creating error message elements.
errorInputClass String ‘error’ The class name added to the input field for invalid inputs
customValidators Object see below Object defining custom validation functions

Built-in Validators

Validators use the data-validate-xxxx attribute to define validation (where xxxx is the validator function name). If not passing additional parameters (sticking to default options), there is no need to include a value for your validator attribute. Here are the built-in validators:

Validator Parameters Values Example
notequal field to compare - required field selector string (i.e. “#First_Name”) <input id="Last_Name" type="text" name="Last_Name" data-validate-notequal="#First_Name">
zip country “us” - ‘merica! (default)
“ca” - America’s hat, Canada (not California - sorry Shannon)
“gb” - Harry’s land
<input id="Zip" type="text" name="Zip_Code" data-validate-zip="ca">
phone country “us” - works for US and Canada (default)
“gb” - guess…
<input id="Phone" type="text" name="Phone" data-validate-phone="gb">

Built-in Methods

Method Parameters Description
validateField(field) field:selected input element Validates a single input and returns an error message string
validateAll() group:selected group element or selector string (optional) Validates all inputs on form or within group element if provided.
showError(field, error) field: selected input element
error: error string
The class name added to error message elements.
removeError(field) field: selected input element Removes any error messages from the specified field.
addBlurListener() N/A Sets an event listener for validating inputs when they lose focus.
addSubmitListener() N/A Sets an event listener for validating the form on submit.

Defining Custom Validators

To define your own validator, add a customValidators entry to your options object. This entry should also be an object that has functions as its named entries. Validator function names should be all lower case. The function should return an error message if the field is invalid or do nothing if it’s valid. See examples for more info.

const validator = new ThFormValidator("contact_form", {
    customValidators: {
        custom: function(field) {
            // run check on field.value
            // if valid - 'return;'
            // return error if invalid
        }
    }
});

If that’s too much work, you can use the pattern attribute to define a custom validation. See next section.

Custom Error Message Text

For custom validators and when using the pattern constraint, add a title attribute to define your own error message:

<input id="Zip" type="text" name="Zip_Code" data-validate-myvalidator title="Please enter a valid ZIP code" required>
<input id="Zip" type="text" name="Zip_Code" pattern="^\d{5}$" maxlength="5" title="Please enter a valid ZIP code" required>

Custom Submit Event Actions

You can disable the built-in submit event listener by passing the disableSubmit option when instantiating the validator class.

const validator = new ThFormValidator("contact_form", {disableSubmit: true});

At this point you can define your own submit listener. Use the validateAll() method to validate the entire form. For validating only a specific group of inputs see the examples section.

document.querySelector("#contact_form").addEventListener("submit", function(e) {
    e.preventDefault(); //stop default submit action
    const errorFields = validator.validateAll(); //validate form
    if(errorFields.length) {
        //We have errors
        errorFields[0].focus();
        errorFields[0].scrollIntoView({behavior: "smooth", block: "center"});
        return; //exit without submitting form
    }
    //do stuff if no errors
    //submit form
    this.submit();
});

Examples

Setting a custom error message class and element

const validator = new ThFormValidator("contact_form", {
    errorMessageClass: 'error-msg',
    errorMessageTag: 'div'
});

Changing the default class for invalid inputs

const validator = new ThFormValidator("contact_form", {
    errorInputClass: 'invalid'
});

Adding a custom, more robust email validator

const validator = new ThFormValidator("contact_form", {
    customValidators: {
        email: function (field) {
            const pattern = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$/;
            const valid = pattern.test(field.value)
            if(valid) return; //do nothing
            return "Please provide a valid email address." //return error message if not valid
        }
    }
}

Apply the validator to the input by setting a data-validate-xxxx attribute, where xxxx is the name of your validator function created above. Pass validation parameters as the value (i.e.: data-validate-phone="us"). If no parameters are required, there is no need to set a value for the attribute:

<input id="Email_Address" type="email" name="Email_Address" maxlength="200" data-validate-email required>

Validating a group of inputs

Pass the group element selector to the validateAll method of your validator object:

const errorFields = validator.validateAll('.step1');
if (errorFields.length) {
    //we have fields with errors
    errorFields[0].focus();
    errorFields[0].scrollIntoView({behavior: "smooth", block: "center"});
} else {
    //do stuff if group is valid
}

Validating a single input

This is not necessary when using the default validateOnBlur option, but included just in case.

Select the field you want to validate and pass it to the validateField method of your validator object:

const field = document.querySelector("#First_Name");
const error = validator.validateField(field);
if (error) {
    //we have an error
    validator.showError(field, error);
    field.focus();
    field.scrollIntoView({behavior: "smooth", block: "center"});
} else {
    validator.removeError(field);
    //do stuff if field is valid
}