Skip to content

Instantly share code, notes, and snippets.

@fregante
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fregante/36ce86cf47f3b7a7d287 to your computer and use it in GitHub Desktop.
Save fregante/36ce86cf47f3b7a7d287 to your computer and use it in GitHub Desktop.
Simple HTML5 forms cross-browser validation (UMD)

bfr Form Validation

Make HTML5 form validation cross-browser and with custom callbacks.

Usage

Create an HTML form with the correct attributes to enable the HTML Form validation (type, pattern and required) and then call bfrFormValidation.setup on the form(s) that need to be validated.

The three callbacks, if specified, will be called when validation is not met or met again.

// normal usage
bfrFormValidation.setup('FORM-SELECTOR', onInvalid, onRevalid, onInvalidAll);
// Browserify usage, with example callbacks
var validation = require('./form-validation');
$(function () {
	validation.setup('FORM-SELECTOR', function (field) {
		//called on an invalid field
		$(field).closest('.Field-container').addClass('Field-container--error');
	}, function (field) {
		//called on an invalid field that has become valid
		$(field).closest('.Field-container').removeClass('Field-container--error');
	}, function (fields) {
		//called on an array of invalid fields
		var $firstInvalid = $(fields).eq(0).closest('.Field-container');
		var target = $firstInvalid.offset().top - 30;
		var duration = Math.abs($(window).scrollTop() - target)+0.2;
		$('html,body').animate({
			scrollTop: target
		}, duration, function () {//watch out, this is called twice because it's on 'html,body'
			fields[0].focus();
		});
	});
});

Support

This is set to only validate required fields. Types of validation supported:

  • type=email
  • type=tel
  • pattern (any regex pattern should work)

The library requires jQuery but, given the size, it can be edited to remove this requirement.

'use strict';
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require('jquery'));
} else {
// Browser globals (root is window)
root.bfrFormValidation = factory(root.jquery);
}
}(this, function ($) {
var emailRegex = /^[^,@\s]+@[^.,@\s]+\.[^.,@\s]$/;//lax
function setup (forms, onInvalid, onRevalid, onInvalidAll) {
var $forms = $(forms);
$forms.each(function () {
var $form = $(this);
var $fields = $(this.elements);
$form.on('submit.bfr-validation', function(e) {
var $invalidFields = $fields.filter(function (i, el) {
return !validateField(el);
});
if ($invalidFields.length) {
if (onInvalid) {
$invalidFields.each(function (i, field) {
onInvalid(field);
});
}
if (onRevalid) {
$invalidFields.on('input.bfr-validation', function () {
var field = this;
if (validateField(field)) {
onRevalid(field);
$(field).off('.bfr-validation');
}
});
}
if (onInvalidAll) {
onInvalidAll($invalidFields.get());
}
return false;
}
});
});
//disable browser validation
$forms.attr('novalidate', true);
return $forms;
}
function validateField (field) {
var $field = $(field);
field = $field.get(0);
var value = field.value;
if(field.hasAttribute('required')) {
if(!value.length) {
return false;
}
if ($field.is('[type=tel]') && value.split(/\d/).length < 7) { //7 is an approximate minimum of numbers
return false;
}
if ($field.is('[type=email]') && !emailRegex.test(value)) {
return false;
}
// [0-9]* triggers the numpad on iOS
if (field.hasAttribute('pattern') && !new RegExp($field.attr('pattern')).test(value)) {
return false;
}
}
return true;
}
function destroy (forms) {
var $forms = $(forms);
$forms.off('.bfr-validation');
$forms.each(function () {
$(this.elements).off('.bfr-validation');
});
}
return {
validateField: validateField,
setup: setup,
destroy: destroy
};
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment