jQuery validation & integration with Bootstrap

Manual HTML form validation can be a time-consuming exercise in frustration, however the jQuery.validate makes it fast and painless, while still allowing powerful custom validation rules, and can easily be adapted to your CSS framework, in this case Bootstrap.

A basic jQuery.validate setup is as simple as importing the js, adding validation tags to your HTML, and calling $form.validate():

<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.12.0/jquery.validate.min.js"></script>
<form id="signupform">
	<input name="name" type="text" minlength="2" maxlength="26" required>
	<label class="radio primary">
		<input type="radio" name="gender" value="m" data-toggle="radio">
		Male
	</label>
	<label class="radio primary">
		<input type="radio" name="gender" value="f" data-toggle="radio">
		Female
	</label>
	<div id="gendererror"></div>
	<input type="email" name="email" required>
	<input class="phone-group" name="phonehome">
	<input class="phone-group" name="phonecell">
</form>
<script>
	$('#signupform').validate();
</script>

This should be mostly self-explanatory – required makes the field mandatory, minlength and maxlength will set string length requirements, while  ‘type=”email”‘ will ensure that the email address is a valid regex for an email.

Calling ‘$(‘#demoform’).validate()’ will turn on validation for the form – giving feedback if a field loses focus while not being valid, and on form submission. If AJAX submission is being used, or it is desired for any other reason, it’s easy to manually run validation on the form and check if it’s valid:

jQuery("#signupform").on("submit", function( event ) {
	event.preventDefault();
	if (jQuery("#signupform").valid()) {
		// Do something
	}
});

$form.validate() can also be used to pass additional options:

jQuery("#signupform").validate({
	rules: {
		phonehome: {
			require_from_group: [1, ".phone-group"]
		},
		phonecell: {
			require_from_group: [1, ".phone-group"]
		},
		gender : {required :true}
	},
	errorPlacement: function(error, element) {
		if (element.attr("name") == "gender") {
			error.insertAfter("#gendererror");
		} else {
			error.insertAfter(element);
		}
	}
});

This will add the custom rule “require_from_group” to the “phonehome” and “phonecell” fields, require that one of the “radiofield” options is selected, whilst the “errorPlacement” section ensures error label placement is correct for the radio field.

Speaking of custom validation rules, these can easily be defined like so:

jQuery.validator.addMethod("require_from_group", function(value, element, options) {
	var $fields = jQuery(options[1], element.form),
		$fieldsFirst = $fields.eq(0),
		validator = $fieldsFirst.data('valid_req_grp') ? $fieldsFirst.data('valid_req_grp') : jQuery.extend({}, this),
		isValid = $fields.filter(function() {
			return validator.elementValue(this);
		}).length >= options[0];

	// Store the cloned validator for future validation
	$fieldsFirst.data('valid_req_grp', validator);
		// If element isn't being validated, run each require_from_group field's validation rules
		if (!jQuery(element).data('being_validated')) {
			$fields.data('being_validated', true);
			$fields.each(function() {
				validator.element(this);
			});
			$fields.data('being_validated', false);
		}
		return isValid;
}, jQuery.format("Please fill at least {0} of these fields."));

// Require old password when setting new one.
jQuery.validator.addMethod("old_pass_if_changing", function(value, element, options) {

	var validator = this,
		oldpass = jQuery(options[0]),
		newpass = jQuery(options[1]);
	if (!oldpass.val() && newpass.val()) var valid = false;
	else var valid = true;

	return valid;
}, jQuery.format("Old password must be supplied when setting new one."));

Integration with Bootstrap is similarly trivial:

// Set jQuery.validate settings for bootstrap integration
jQuery.validator.setDefaults({
	highlight: function(element) {
		jQuery(element).closest('.form-group').addClass('has-error');
	},
	unhighlight: function(element) {
		jQuery(element).closest('.form-group').removeClass('has-error');
	},
	errorElement: 'span',
	errorClass: 'label label-danger',
	errorPlacement: function(error, element) {
		if(element.parent('.input-group').length) {
			error.insertAfter(element.parent());
		} else {
			error.insertAfter(element);
		}
	}
});

This will add the “has-error” class to each element that did not pass validation, and the type, classes and placement of validation error messages can be controlled using “errorElement”, “errorClass” and “errorPlacement”.

jQuery AJAX form submission
Rebuilding VirtualBox with missing VDI snapshots