Getting started

Add the script, put data-validation on the fields that need checking, and call $.validate(). Everything after that is refinement.

Requirements

jQuery 1.8 or newer, including jQuery 3 and jQuery 4. No other runtime dependency. numeral.js is optional and only relevant to one sanitizer.

Installing

CDN

The quickest way in. jsDelivr serves the tagged release straight from GitHub, so nothing needs installing:

CDN — pinned to 4.4.0
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/premento/[email protected]/dist/jquery.form-validator.js"></script>

<script>
  $.validate();
</script>
Pin the version

The URL above is pinned to @4.4.0. Dropping the tag gives you the default branch, which changes without warning and will eventually break your form. Always pin a release.

Modules and language files sit beside the core file on the same CDN, so the plugin finds them without any extra configuration:

JavaScript
$.validate({
  modules: 'security, date',   // fetched from the CDN alongside the core file
  lang: 'sv'
});

For a smaller download, point at the minified build instead:

Minified
<script src="https://cdn.jsdelivr.net/gh/premento/[email protected]/dist/jquery.form-validator.min.js"></script>

The bundled theme is on the CDN too, if you want the default styling:

HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/premento/[email protected]/dist/theme-default.css">

Self-hosted script tag

Download a release, or take the built files from the repository, and serve them yourself:

HTML
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="form-validator/jquery.form-validator.min.js"></script>

Modules live beside the core file and are fetched on demand when you name them in modules. Point the plugin somewhere else with an explicit path if your layout differs:

JavaScript
$.validate({
  modules: 'security, date'
});

// Or load them yourself, from a path of your choosing:
$.formUtils.loadModules('security, date', '/assets/js/form-validator/');

npm

Terminal
npm install jquery-form-validator

ES modules

Every module is a real entry point, so a bundler resolves it statically. Importing a module registers its validators — there is no runtime script injection, which also means the plugin works under a strict Content-Security-Policy.

JavaScript
import jQuery from 'jquery-form-validator';
import 'jquery-form-validator/modules/security';
import 'jquery-form-validator/lang/sv';
import 'jquery-form-validator/css';

jQuery.validate({ lang: 'sv' });
Modules you import are not fetched again

If a module has already registered itself through an import, naming it in modules is a no-op rather than a second network request. Mixing the two styles is safe.

CommonJS

JavaScript
const jQuery = require('jquery-form-validator');
require('jquery-form-validator/modules/security');

TypeScript

Declarations ship with the package, so $.validate(), the configuration object and $.formUtils are all typed. Nothing to install separately.

JavaScript
import 'jquery-form-validator';

$.validate({
  modules: 'security',
  errorMessagePosition: 'top',
  onSuccess: function ($form) { return true; }
});

Your first form

Three fields, three rules, one call.

HTML
<form action="/signup" method="post" id="signup">
  <p>
    <label for="name">Name</label>
    <input id="name" name="name" data-validation="required">
  </p>
  <p>
    <label for="email">Email</label>
    <input id="email" name="email" data-validation="email">
  </p>
  <p>
    <label for="pw">Password</label>
    <input id="pw" name="pw" type="password"
           data-validation="length" data-validation-length="min12">
  </p>
  <button type="submit">Sign up</button>
</form>
JavaScript
$.validate({ form: '#signup' });

Rules are separated by spaces, so a field can carry several. They run in order and the first failure is what gets reported:

HTML
<input name="email" data-validation="required email">

Making a rule optional

data-validation-optional="true" means "check this, but only if something was entered". An empty value passes; a malformed one still fails.

HTML
<input name="website" data-validation="url" data-validation-optional="true">

Custom messages

Per field, or per rule on that field:

HTML
<!-- One message for whichever rule fails -->
<input name="email" data-validation="required email"
       data-validation-error-msg="We need an address to reach you on">

<!-- A different message per rule -->
<input name="email" data-validation="required email"
       data-validation-error-msg-required="This one is required"
       data-validation-error-msg-email="That does not look like an email address">

Where errors appear

By default each message is written next to its field. Setting errorMessagePosition: 'top' collects them into a single summary above the form instead, with every entry linking to the field it describes.

JavaScript
$.validate({
  errorMessagePosition: 'top'   // 'inline' is the default
});
Pick the summary for long forms

A summary is easier to act on when a failed submit produces several errors at once, and it is the pattern assistive technology users are most likely to expect. Focus moves into it automatically. See the error summary.

When validation runs

MomentWhat happens
On submitEvery field is validated. Submission is blocked if any fail.
On blurThe field that lost focus is validated. Controlled by validateOnBlur.
While typingOnly after a field has already failed — it then re-checks on every input event so the fix is confirmed immediately.
On clickCheckboxes and radios validate as soon as they are clicked. Controlled by validateCheckboxRadioOnClick.
On a named eventWith validateOnEvent: true, an element carrying data-validation-event="change" validates on that event.
Why <code>input</code> and not <code>keyup</code>

A value can change without a key ever being released — paste, autofill, drag-and-drop, speech input, IME composition. Those were all invisible to the key-event handling used before 3.0, which left a corrected field still showing an error.

Adding the stylesheet

A default theme ships with the package. It is entirely optional — the plugin only adds class names, so your own CSS can take over completely.

HTML
<link rel="stylesheet" href="form-validator/theme-default.css">

On a Bootstrap 4 or 5 page, skip the theme and tell the plugin which release you are on so it emits the class names that framework already styles:

JavaScript
$.validate({ bootstrap: 5 });

Next steps