jQuery Validatable is a jQuery plugin for complex form validation. It provides a lightweight framework for interacting with forms and is aimed at front-end developers.

It's designed to work with Bootstrap markup, mainly due to making use of has-success and has-error classes for validation states.

Requirements:
Form structure
<form class="form-default form-validatable" id="form1"> form containing one or more groups
	<div class="form-group group-validatable" id="group1"> group containing one or more fields
		<label class="control-label" for="text1">
			Text
			<i class="glyphicon glyphicon-ok has-success icon-validatable"></i>
			<i class="glyphicon glyphicon-remove has-error icon-validatable"></i>
		</label>
		<input type="text" class="form-control field-validatable" name="text1" id="text1"> field
		<span class="help-block help-block-validatable">Default help text.</span>
		<span class="help-block has-success help-block-validatable">Field valid.</span>
		<span class="help-block has-error help-block-validatable">Field invalid.</span>
	</div>
</form>
Form
  • tag: form
  • class attribute: form-validatable
  • attribute: id
<form class="form-default form-validatable" id="form1">
Group
  • tag: div
  • class attributes: group-validatable
  • attribute: id
<div class="group-validatable" id="group1">
Label status icons
  • tag: i
  • valid class attribute: has-success icon-validatable
  • invalid class attribute: has-error icon-validatable
<label class="control-label" for="text1">
	Label
	<i class="glyphicon glyphicon-ok has-success icon-validatable"></i>
	<i class="glyphicon glyphicon-remove has-error icon-validatable"></i>
</label>
Field
  • tag: input, select, textarea
  • type attribute text, checkbox, radio, hidden
  • class attribute: field-validatable
  • attribute: id
<input type="text" class="form-control field-validatable" name="text1" id="text1">
<select class="form-control field-validatable" name="select1" id="select1">
Help block
  • tag: span
  • neutral class attributes: help-block help-block-validatable
  • valid class attributes: help-block has-success help-block-validatable
  • invalid class attributes: help-block has-error help-block-validatable
<span class="help-block help-block-validatable">Default help text.</span>
<span class="help-block has-success help-block-validatable">Field valid.</span>
<span class="help-block has-error help-block-validatable">Field invalid.</span>
Bootstrap form
Default form
Default help text Success help text Error help text
Default help text Success help text Error help text

Default help text Success help text Error help text
Default help text Success help text Error help text
Default help text Success help text Error help text
Default help text Success help text Error help text

Default help text Success help text Error help text
.00
Default help text Success help text Error help text
.00
Default help text Success help text Error help text

Default help text Success help text Error help text
Y
M
Default help text Success help text Error help text
Default help text Success help text Error help text

Default help text Success help text Error help text
Validator
$('#form1').validatable();
$('#form1').validatable(
	{ global options
		validateOn: {
			change: false, ignore onchange event
			blur: true,
			submit: true
		},
		className: {
			valid: 'has-success', class applied to a valid form-group
			invalid: 'has-error' class applied to an invalid form-group
		}
	},
	{ element options (keys match form, group or element id attribute)
		form1: {
			on: {
				submit: function(event, Form){ form event observer
					alert("Form #"+form.id+" cannot be submitted.");
					return false; returning "false" stops event propagation
				}
			}
		},
		text1: {
			required: false field is optional
		},
		text2: {
			rules: {
				regex: /^07[0-9]{8,9}$/ field must match the regular expression to be valid
			},
			filter: /[a-zA-Z]/ allow letters only
		},
		select1: {
			validate: function(){ replaces build-in validation
				return this.val() == 'option1';
			}
		},
		group4: { group must contain at least one, but no more than 3 valid fields
			rules: {
				min: 1,
				max: 3
			}
		}
	}
);
Options

Global options are merged into form, group and field options.

Options can be set globally (as a property of the first parameter of validatable) or attached to a group/field.

option allowed elements
validateOn.change enables validation on field change
validateOn.blur enables validation on field blur
validateOn.submit enables validation on form submit
className.valid class applied to form-group div on successful group validation (default: has-success)
className.invalid class applied to form-group div on failed group validation (default: has-error)
on.* attaches observer to form/group/field events
required set to false to allow field to be empty (if it's not empty all validation rules will still be applied)
validate overrides build-in validation rules
rules.* validation rules
filter keypress filter (RegExp)
Event types
type object
readyFormon form/group/field successful creation
submitFormon form submit, before any validation
validFormon successful form/group/field validation
invalidFormon failed form/group/field validation
changeFieldon field change
blurFieldon field blur
Observers

The event propagation is stopped if the observer returns strict false.

An observer must be attached via on option and accept two parameters:

  • event - Event object (for default browser event)
  • obj - either Form, Group or Field object
$('#form1').validatable({}, {
	text1: {
		on: {
			change: function(event, Field){
				console.log('The value of field ', Field.id, 'has changed to', Field.val());
			}
		}
	}
});
Validators

Custom validators take precedence over build-in validation and any custom rules.

A validator can be attached via validate option and is called in the caller's context:

A validator can return one of the following values:

  • strict true - the element is valid
  • strict false - the element is invalid
  • strict null - the element is either empty but optional, has not been validated or its state is unknown
$('#form1').validatable({}, {
	text1: {
		validate: function(){
			var value = this.val();
			return (value >= 1 && value <= 3);
		}
	}
});
Rules

Custom rules take precedence over build-in validation.

Predefined validation rules can be attached to a group or field via rules option.

If there is more than one rule attached to an element, all of them must be fulfilled for the element to be considered valid.

element rule name value type description
groupequalsstring/integerrequired value of at least one field
groupminintminimum number of valid fields (for instance selected checkboxes)
groupmaxintmaximum number of valid fields (for instance selected checkboxes)
fieldequalsstring/integerrequired field value
fieldregexRegexfield value must match the provided regular expression
fieldminintminimum value
fieldmaxintmaximum value
$('#form1').validatable({}, {
	group1: {
		rules: {
			min: 1,
			max: 3
		}
	}
});
$('#form1').validatable({}, {
	text1: {
		rules: {
			regex: /^0[0-9]{9,10}$/
		}
	}
});
Examples
Text field - at least two alpha-numeric characters with filter
Enter at least two alpha-numeric characters. Looks good! Invalid!
$('#exampleForm1').validatable({}, {
	exampleText1: {
		rules: { regex: /^[a-zA-Z]{2,}$/ },
		filter: /[a-zA-Z]/
	}
});
Select field - accept only subset of options
Select Yes or No. Looks good! Invalid!
$('#exampleForm2').validatable({}, {
	exampleSelect1: { validate: function(){
		return ['yes', 'no'].indexOf(this.val()) !== -1;
	}}
});
Multi-select fields - validate year / month
Y
M
Select at least 3 months Looks good! Invalid!
$('#exampleForm3').validatable({}, {
	exampleYearMonthGroup: { validate: function(){
		return this.fields.exampleYears.val()*12 + this.fields.exampleMonths.val() >= 3;
	}}
});
Validate date of birth
var dob = {
	dmy: function(form){
		return {
			d: form.groups.dobGroup.fields.exampleDobD.validate(),
			m: form.groups.dobGroup.fields.exampleDobM.validate(),
			y: form.groups.dobGroup.fields.exampleDobY.validate()
		};
	},
	validate: {
		group: function(){
			var dmy = dob.dmy(this.form);
			return (dmy.d && dmy.m && dmy.y) ? true : null;
		},
		form: function(){
			var dmy = dob.dmy(this);
			if (!dmy.d || !dmy.m || !dmy.y) {
				this.groups.dobGroup.invalid();
				return false;
			}
			return true;
		}
	}
};
$('#exampleForm4').validatable({}, {
	exampleForm4: { on: { submit: function(event, form){
		if (false === dob.validate.form.call(form)){
			event.preventDefault();
			return false;
		}
	}}},
	dobGroup: { validate: dob.validate.group }
});
Datepicker
<input type="text"
	class="form-control field-validatable datepicker-validatable"
	id="dpPreview"
	data-alt-field="dp"
>
<input type="hidden" id="dp" name="dp">
$('#exampleForm5 .datepicker-validatable').each(function(){
	var altField = '#'+$(this).data('alt-field');
	$(this).datepicker({
		altField: altField,
		altFormat: 'yy-mm-dd',
		dateFormat: 'dd/mm/yy'
	});
	$(this).bind('focus', function(event){
		$(this).blur()
	});
});
$('#exampleForm5').validatable({}, {
	dpGroup: { validateOn: { blur: false }}
});