JavaScript API
Everything the plugin exposes: the entry point, the jQuery methods it adds, the
$.formUtils toolbox, and the events you can hook into.
$.validate(config)
Sets up validation on the matched forms. Safe to call again — the second call removes the handlers the first one attached before re-binding.
$.validate({
form: '#checkout',
modules: 'security'
});See Configuration for every option.
$.setupValidation(config)
From the jsconf module. Declares rules in JavaScript, applies them as attributes,
then calls $.validate().
$.setupValidation({
form: '#my-form',
validate: {
'user': {validation: 'length', length: 'min4'},
'email': {validation: 'email'}
}
});jQuery methods
| Method | Description |
|---|---|
$form.isValid(language, config, displayErrors) | Validates every field and returns a boolean. Pass false as the third argument to check without showing anything. |
$input.validate(callback, config, language) | Validates a single field and calls back with the result. |
$form.validateOnBlur(language, config) | Binds blur validation to the form's fields. |
$form.validateOnEvent(language, config) | Binds validation to the events named by data-validation-event. |
$input.validateOnInput(language, config) | Re-validates the field as its value changes. |
$input.removeInputValidation() | Stops that live re-validation. |
$input.validateInputOnBlur(language, config, attachInputEvent, eventContext) | Validates one field and renders the outcome. |
$input.restrictLength($counter) | Caps typing at the number in $counter and counts down as the user types. |
$form.showHelpOnFocus(attrName) | Wires up data-validation-help text. |
$form.addSuggestions(settings) | Wires up data-suggestions dropdowns. |
$input.valAttr(name, value) | Gets, sets or removes a data-validation-* attribute. |
// Check without rendering anything
if ($('#signup').isValid(null, null, false)) {
submitOverXhr();
}
// Validate one field
$('#email').validate(function (isValid, $el) {
console.log($el.attr('name'), isValid);
});
// Character countdown
$('#bio').restrictLength($('#chars-left'));$.fn.validateForm (use isValid), $.fn.validateOnKeyUp (use validateOnInput) and $.fn.removeKeyUpValidation (use removeInputValidation) still work and log a warning.
$.formUtils
Registering things
| Member | Description |
|---|---|
addValidator(validator) | Registers a validation rule. |
addAsyncValidator(validator) | Registers a rule that resolves asynchronously. |
addSanitizer(sanitizer) | Registers a data-sanitize transform. |
validators | The registry, keyed validate_name. |
sanitizers | The sanitizer registry. |
Modules
| Member | Description |
|---|---|
loadModules(names, path, callback) | Loads modules, optionally from a given path. |
registerLoadedModule(name) | Marks a module as present, so it is not fetched again. |
hasLoadedModule(name) | Whether a module has registered. |
normalizeModuleName(name) | Lower-cases and strips a trailing .js. |
Validating
| Member | Description |
|---|---|
validateInput($el, language, config, $form, eventContext) | Validates one element and returns {isValid, errorMsg, shouldChangeDisplay}. |
getValue(query, $parent) | Reads a value, handling radio and checkbox groups. |
defaultConfig() | A fresh copy of the default configuration. |
haltValidation | Set to true inside a validator to suspend validation and block submission. |
numericRangeCheck(value, range) | Shared min4 / max9 / 1-4 parsing. |
parseDate(value, format, addLeadingZeros) | Returns [year, month, day], or false. |
warn(message) | Logs through the plugin's own console channel. |
Messages and locale
| Member | Description |
|---|---|
LANG | The active message catalogue. |
formatMessage(template, params, count) | Substitutes {0} placeholders and selects a plural form. |
selectPluralForm(forms, count) | Picks a CLDR plural category via Intl.PluralRules. |
locale() | The locale used for Intl formatting. |
localeDecimalSeparator() | The separator this locale writes numbers with. |
unformatNumber(value) | Strips grouping characters from a formatted number. |
Accessibility helpers
| Member | Description |
|---|---|
a11y.markInvalid($input) | Sets aria-invalid="true". |
a11y.describeError($input, $message) | Links the message to the field with aria-describedby and makes it a polite live region. |
a11y.clearError($input) | Removes the invalid flag and detaches only the token the plugin added. |
a11y.ensureInputId($input) | Gives the field an id so a summary entry can link to it. |
a11y.focus($elem) | Moves focus, making a container focusable first if needed. |
a11y.prefersReducedMotion() | Whether the visitor has asked for reduced motion. |
Custom validators
$.formUtils.addValidator({
name: 'even',
validatorFunction: function (value, $el, config, language, $form) {
return parseInt(value, 10) % 2 === 0;
},
errorMessage: 'Please give an even number',
errorMessageKey: 'badEvenNumber'
});<input data-validation="even">| Property | Required | Description |
|---|---|---|
name | yes | The rule name, as written in data-validation. No hyphens. |
validatorFunction | yes | Returns true, false, or null to mean "cannot answer yet". |
errorMessage | yes | Fallback text, used when the language file has no entry. |
errorMessageKey | yes | Key looked up in $.formUtils.LANG. May be a function of the config. |
validateOnInput | no | Set false to skip this rule while the user is still typing. Defaults to true. |
The validator function receives:
| Argument | What it is |
|---|---|
value | The field value, after any sanitizers have run. |
$el | The field, as a jQuery object. |
config | The active configuration. |
language | The active message catalogue. |
$form | The form the field belongs to. |
eventContext | 'blur', 'input', 'submit', 'click'. |
Reading your own attributes
$.formUtils.addValidator({
name: 'multipleof',
validatorFunction: function (value, $el, config, language) {
var factor = parseInt($el.valAttr('factor'), 10);
if (isNaN(factor)) {
$.formUtils.warn('data-validation-factor is missing');
return true;
}
this.errorMessage = 'Must be a multiple of ' + factor;
return parseInt(value, 10) % factor === 0;
},
errorMessage: '',
errorMessageKey: ''
});<input data-validation="multipleof" data-validation-factor="5">Asynchronous validators
Use addAsyncValidator when the answer needs a round trip. The first argument is a
callback you invoke with the result; form submission waits for it.
$.formUtils.addAsyncValidator({
name: 'unique_username',
validatorFunction: function (done, value, $el, config, language, $form) {
$.getJSON('/api/username?u=' + encodeURIComponent(value))
.done(function (res) { done(res.available); })
.fail(function () { done(true); }); // fail open
},
errorMessage: 'That username is taken',
errorMessageKey: 'badUsername'
});Checks wait data-validation-debounce milliseconds (500 by default) before calling out, so a visitor who edits and leaves a field several times produces one request carrying the value they finished on. Submitting is never debounced — the request goes out at once. While a check is in flight the field is marked aria-busy rather than disabled, so it keeps focus and stays in the tab order.
Custom sanitizers
$.formUtils.addSanitizer({
name: 'stripSpaces',
sanitizerFunction: function (value, $input, config) {
return value.replace(/\s+/g, '');
}
});<input data-sanitize="stripSpaces" data-validation="creditcard">Events
All of these are jQuery events. Field-level ones bubble, so you can delegate from the form.
On a field
| Event | Arguments | When |
|---|---|---|
beforeValidation | value, language, config | Before a field is validated. Call evt.stopImmediatePropagation() to take over the skip decision. |
validation | isValid | Immediately after a field is judged. |
afterValidation | result, eventContext | After the result object is complete. |
validationErrorDisplay | $input, $messageElement | Just before an error message is written. Fired on window. |
On the form or window
| Event | Arguments | When |
|---|---|---|
formValidationPluginInit | config | $.validate() has been called. Fired on window. |
formValidationSetup | $form, config | A form is being set up. |
validatorsLoaded | $form, config | Every module named in modules has registered. Fired on window. |
html5ValidationAttrsFound | — | The html5 module translated some attributes. |
From specific validators
| Event | Arguments | From |
|---|---|---|
ageCalculated | age | birthdate |
imageValidation | isValid | dimension |
genderDerived | gender | swesec |
complexityRequirementValidation | isValid, requirement | complexity |
// Live password requirement checklist
$('#password').on('complexityRequirementValidation', function (e, valid, name) {
$('#req-' + name).toggleClass('met', valid);
});
// Show the age as a birthdate is typed
$('#dob').on('ageCalculated', function (e, age) {
$('#age-readout').text(age + ' years old');
});
// Delegate from the form
$('#signup').on('afterValidation', '[data-validation]', function (e, result) {
if (!result.isValid) {
analytics.track('field_error', {field: this.name});
}
});Suspending validation
Setting $.formUtils.haltValidation = true inside a validator stops the run and
blocks submission until something clears it. This is how the asynchronous validators hold a
form while a request is outstanding.
TypeScript
Declarations ship with the package and are wired into the exports map, so both
import and require resolve the right ones. Nothing to install.
import 'jquery-form-validator';
$.validate({
modules: 'security',
errorMessagePosition: 'top',
onSuccess: function ($form) { return true; }
});