Browse Source

Merge branch 'master' into v0.5.0

Conflicts:
	CHANGELOG.md
	bootstrapValidator.jquery.json
	bower.json
	dist/css/bootstrapValidator.min.css
	dist/js/bootstrapValidator.js
	dist/js/bootstrapValidator.min.js
	package.json
	src/js/bootstrapValidator.js
nghuuphuoc 11 years ago
parent
commit
639254c19a

+ 57 - 34
CHANGELOG.md

@@ -4,34 +4,57 @@
 
 * [#121](https://github.com/nghuuphuoc/bootstrapvalidator/issues/121): Add events for form validate successfully or not
 
-## v0.4.3 (2005-05-05)
-
-* [#77](https://github.com/nghuuphuoc/bootstrapvalidator/issues/77): Add ```file``` validator
-* [#179](https://github.com/nghuuphuoc/bootstrapvalidator/issues/179): Add ```vat``` validator, support 32 countries
-* [#198](https://github.com/nghuuphuoc/bootstrapvalidator/pull/198): Add Canadian Postal Code support for the [```zipCode``` validator](http://bootstrapvalidator.com/validators/zip-code/), thanks to [@Francismori7](https://github.com/Francismori7)
-* [#201](https://github.com/nghuuphuoc/bootstrapvalidator/issues/201): ```choice``` validator supports select element
+## v0.4.5 (not released yet)
+
+* [#233](https://github.com/nghuuphuoc/bootstrapvalidator/issues/233): Add ```threshold``` option
+* [#232](https://github.com/nghuuphuoc/bootstrapvalidator/issues/232): Add ```id``` validator
+* When parsing options from HTML attributes, don't add the field which hasn't validators. It improves fixes for [#191](https://github.com/nghuuphuoc/bootstrapvalidator/issues/191), [#223](https://github.com/nghuuphuoc/bootstrapvalidator/issues/223)
+
+## v0.4.4 (2014-05-05)
+
+* Add ```$.fn.bootstrapValidator.helpers.mod_11_10``` method that implements modulus 11, 10 (ISO 7064) algorithm. The helper is then reused in validating [German and Croatian VAT](http://bootstrapvalidator.com/validators/vat/) numbers
+* Add ```$.fn.bootstrapValidator.helpers.mod_37_36``` method that implements modulus 37, 36 (ISO 7064) algorithm, used in GRid validator
+* [#213](https://github.com/nghuuphuoc/bootstrapvalidator/issues/213): Add EAN (International Article Number) validator
+* [#214](https://github.com/nghuuphuoc/bootstrapvalidator/issues/214): Add GRId (Global Release Identifier) validator
+* [#215](https://github.com/nghuuphuoc/bootstrapvalidator/issues/215): Add IMEI (International Mobile Station Equipment Identity) validator
+* [#216](https://github.com/nghuuphuoc/bootstrapvalidator/issues/216): Add ISMN (International Standard Music Number) validator
+* [#217](https://github.com/nghuuphuoc/bootstrapvalidator/issues/217): Add ISSN (International Standard Serial Number) validator
+* [#191](https://github.com/nghuuphuoc/bootstrapvalidator/issues/191), [#223](https://github.com/nghuuphuoc/bootstrapvalidator/issues/223): Support using both the ```name``` attribute and ```selector``` option for field
+* [#206](https://github.com/nghuuphuoc/bootstrapvalidator/issues/206): Indicate success/error tab
+* [#220](https://github.com/nghuuphuoc/bootstrapvalidator/issues/220): Add UK postcode support for the [```zipCode``` validator](http://bootstrapvalidator.com/validators/zipCode/)
+* [#229](https://github.com/nghuuphuoc/bootstrapvalidator/issues/229): The [```date``` validator](http://bootstrapvalidator.com/validators/date/) supports seconds
+* [#231](https://github.com/nghuuphuoc/bootstrapvalidator/issues/231): Wrong prefix of Laser credit card number
+
+## v0.4.3 (2014-04-26)
+
+* Add ```$.fn.bootstrapValidator.helpers.luhn``` method that implements the Luhn algorithm
+* [#77](https://github.com/nghuuphuoc/bootstrapvalidator/issues/77): Add [```file``` validator](http://bootstrapvalidator.com/validators/file/)
+* [#179](https://github.com/nghuuphuoc/bootstrapvalidator/issues/179): Add [```vat``` validator](http://bootstrapvalidator.com/validators/vat/), support 32 countries
+* [#198](https://github.com/nghuuphuoc/bootstrapvalidator/pull/198): Add Canadian Postal Code support for the [```zipCode``` validator](http://bootstrapvalidator.com/validators/zipCode/), thanks to [@Francismori7](https://github.com/Francismori7)
+* [#201](https://github.com/nghuuphuoc/bootstrapvalidator/issues/201): The [```choice``` validator](http://bootstrapvalidator.com/validators/choice/) supports ```select``` element
 * [#202](https://github.com/nghuuphuoc/bootstrapvalidator/issues/202): Activate tab containing the first invalid field
 * [#205](https://github.com/nghuuphuoc/bootstrapvalidator/issues/205): Plugin method invocation
-* [#209](https://github.com/nghuuphuoc/bootstrapvalidator/issues/209): The ```excluded: ':disabled'``` setting does not work on IE 8, thanks to [@adgrafik](https://github.com/adgrafik)
-* [#210](https://github.com/nghuuphuoc/bootstrapvalidator/issues/210): ```isbn``` validator accepts letters and special characters
+* [#207](https://github.com/nghuuphuoc/bootstrapvalidator/issues/207): IE8 error. The field is only validated when its value is changed. It also fixes [#153](https://github.com/nghuuphuoc/bootstrapvalidator/issues/153), [#193](https://github.com/nghuuphuoc/bootstrapvalidator/issues/193), [#197](https://github.com/nghuuphuoc/bootstrapvalidator/issues/197)
+* [#209](https://github.com/nghuuphuoc/bootstrapvalidator/issues/209): The [```excluded: ':disabled'``` setting](http://bootstrapvalidator.com/settings/#excluded) does not work on IE 8, thanks to [@adgrafik](https://github.com/adgrafik)
+* [#210](https://github.com/nghuuphuoc/bootstrapvalidator/issues/210): The [```isbn``` validator](http://bootstrapvalidator.com/validators/isbn/) accepts letters and special characters
 
 ## v0.4.2 (2014-04-19)
 
-* [#168](https://github.com/nghuuphuoc/bootstrapvalidator/pull/168): Add siren and siret validators, thanks to [@jswale](https://github.com/jswale)
-* [#177](https://github.com/nghuuphuoc/bootstrapvalidator/issues/177): Add Vehicle Identification Number (VIN) validator
-* [#184](https://github.com/nghuuphuoc/bootstrapvalidator/issues/184): Add ```excluded``` option
+* [#168](https://github.com/nghuuphuoc/bootstrapvalidator/pull/168): Add [siren](http://bootstrapvalidator.com/validators/siren/) and [siret](http://bootstrapvalidator.com/validators/siret/) validators, thanks to [@jswale](https://github.com/jswale)
+* [#177](https://github.com/nghuuphuoc/bootstrapvalidator/issues/177): Add [Vehicle Identification Number (VIN) validator](http://bootstrapvalidator.com/validators/vin/)
+* [#184](https://github.com/nghuuphuoc/bootstrapvalidator/issues/184): Add [```excluded``` option](http://bootstrapvalidator.com/settings/#excluded)
 * [#171](https://github.com/nghuuphuoc/bootstrapvalidator/pull/171): The [```phone``` validator](http://bootstrapvalidator.com/validators/phone/) now supports +1 country code and area code for US phone number, thanks to [@tomByrer](https://github.com/tomByrer)
 * [#173](https://github.com/nghuuphuoc/bootstrapvalidator/pull/173): The [```remote``` validator](http://bootstrapvalidator.com/validators/remote/) allows to override ```name``` option, thanks to [@jswale](https://github.com/jswale)
 * [#178](https://github.com/nghuuphuoc/bootstrapvalidator/pull/178): Do not validate fields that ```enabled``` is set to ```false```, thanks to [@henningda](https://github.com/henningda)
-* [#182](https://github.com/nghuuphuoc/bootstrapvalidator/pull/182): Improve [```zipCode``` validator](http://bootstrapvalidator.com/validators/zip-code/), thanks to [@gercheq](https://github.com/gercheq)
+* [#182](https://github.com/nghuuphuoc/bootstrapvalidator/pull/182): Improve [```zipCode``` validator](http://bootstrapvalidator.com/validators/zipCode/), thanks to [@gercheq](https://github.com/gercheq)
 
 ## v0.4.1 (2014-04-12)
 
 * [#144](https://github.com/nghuuphuoc/bootstrapvalidator/issues/144), [#158](https://github.com/nghuuphuoc/bootstrapvalidator/issues/158): Fixed an issue that the custom submit handler is not fired from the second time
-* [#106](https://github.com/nghuuphuoc/bootstrapvalidator/issues/106): Prevent the ```validate()``` method from submit the form automatically. So we can call ```validate()``` to validate the form
+* [#106](https://github.com/nghuuphuoc/bootstrapvalidator/issues/106): Prevent the [```validate()```](http://bootstrapvalidator.com/api/#validate) method from submit the form automatically. So we can call ```validate()``` to validate the form
 * [#131](https://github.com/nghuuphuoc/bootstrapvalidator/issues/131): Doesn't trigger validation on the first focus
 * [#145](https://github.com/nghuuphuoc/bootstrapvalidator/issues/145): The row state is now only marked as success if all fields on it are valid
-* [#157](https://github.com/nghuuphuoc/bootstrapvalidator/issues/157): Added support for element outside of form using the ```selector``` option
+* [#157](https://github.com/nghuuphuoc/bootstrapvalidator/issues/157): Added support for element outside of form using the [```selector```](http://bootstrapvalidator.com/settings/#fields) option
 * [#159](https://github.com/nghuuphuoc/bootstrapvalidator/issues/159), [#163](https://github.com/nghuuphuoc/bootstrapvalidator/pull/163): User doesn't need to submit the form twice when remote validator complete, thanks to [@jswale](https://github.com/jswale)
 * [#162](https://github.com/nghuuphuoc/bootstrapvalidator/pull/162): Fix errors in IE 8, thanks to [@adgrafik](https://github.com/adgrafik)
 * [#166](https://github.com/nghuuphuoc/bootstrapvalidator/issues/166), [#167](https://github.com/nghuuphuoc/bootstrapvalidator/pull/167): The [```phone``` validator](http://bootstrapvalidator.com/validators/phone/) now also checks the length of US phone number, thanks to [@gercheq](https://github.com/gercheq)
@@ -67,13 +90,13 @@ Field attributes:
 
 HTML 5 attribute      | Validator
 ----------------------|----------
-```min="..."```       | [```greaterThan``` validator](http://bootstrapvalidator.com/validators/greater-than/)
-```max="..."```       | [```lessThan``` validator](http://bootstrapvalidator.com/validators/less-than/)
-```maxlength="..."``` | [```stringLength``` validator](http://bootstrapvalidator.com/validators/string-length/)
+```min="..."```       | [```greaterThan``` validator](http://bootstrapvalidator.com/validators/greaterThan/)
+```max="..."```       | [```lessThan``` validator](http://bootstrapvalidator.com/validators/lessThan/)
+```maxlength="..."``` | [```stringLength``` validator](http://bootstrapvalidator.com/validators/stringLength/)
 ```pattern="..."```   | [```regexp``` validator](http://bootstrapvalidator.com/validators/regexp/)
-```required```        | [```notEmpty``` validator](http://bootstrapvalidator.com/validators/not-empty/)
-```type="color"```    | [```hexColor``` validator](http://bootstrapvalidator.com/validators/hex-color/)
-```type="email"```    | [```emailAddress``` validator](http://bootstrapvalidator.com/validators/email-address/)
+```required```        | [```notEmpty``` validator](http://bootstrapvalidator.com/validators/notEmpty/)
+```type="color"```    | [```hexColor``` validator](http://bootstrapvalidator.com/validators/hexColor/)
+```type="email"```    | [```emailAddress``` validator](http://bootstrapvalidator.com/validators/emailAddress/)
 ```type="range"```    | [```between``` validator](http://bootstrapvalidator.com/validators/between/)
 ```type="url"```      | [```uri``` validator](http://bootstrapvalidator.com/validators/uri/)
 
@@ -133,7 +156,7 @@ $(form).bootstrapValidator({
 * [#128](https://github.com/nghuuphuoc/bootstrapvalidator/issues/128): Add [```numeric``` validator](http://bootstrapvalidator.com/validators/numeric/)
 * [#135](https://github.com/nghuuphuoc/bootstrapvalidator/issues/135): Add [```integer``` validator](http://bootstrapvalidator.com/validators/integer/)
 * [#138](https://github.com/nghuuphuoc/bootstrapvalidator/issues/138): Add [```hex``` validator](http://bootstrapvalidator.com/validators/hex/)
-* [#139](https://github.com/nghuuphuoc/bootstrapvalidator/issues/139): Add [```stringCase``` validator](http://bootstrapvalidator.com/validators/string-case/) to check a string is lower or upper case
+* [#139](https://github.com/nghuuphuoc/bootstrapvalidator/issues/139): Add [```stringCase``` validator](http://bootstrapvalidator.com/validators/stringCase/) to check a string is lower or upper case
 * [#137](https://github.com/nghuuphuoc/bootstrapvalidator/issues/137): Register the plugin with [jQuery plugins site](http://plugins.jquery.com/)
 * [#133](https://github.com/nghuuphuoc/bootstrapvalidator/issues/133): The [```regexp``` validator](http://bootstrapvalidator.com/validators/regexp/) allows to pass a string
 * [#140](https://github.com/nghuuphuoc/bootstrapvalidator/pull/140): Do not validate hidden (```type="hidden"```) and invisible element, thanks to [@easonhan007](https://github.com/easonhan007)
@@ -146,7 +169,7 @@ $(form).bootstrapValidator({
 
 * [#50](https://github.com/nghuuphuoc/bootstrapvalidator/issues/50): Don't validate disabled element
 * [#34](https://github.com/nghuuphuoc/bootstrapvalidator/issues/34), [#105](https://github.com/nghuuphuoc/bootstrapvalidator/issues/105): Cannot call ```form.submit()``` inside [```submitHandler```](http://bootstrapvalidator.com/settings/#submit-handler)
-* [#77](https://github.com/nghuuphuoc/bootstrapvalidator/issues/77), [#117](https://github.com/nghuuphuoc/bootstrapvalidator/issues/117): The [```notEmpty``` validator](http://bootstrapvalidator.com/validators/not-empty/) doesn't work on file input
+* [#77](https://github.com/nghuuphuoc/bootstrapvalidator/issues/77), [#117](https://github.com/nghuuphuoc/bootstrapvalidator/issues/117): The [```notEmpty``` validator](http://bootstrapvalidator.com/validators/notEmpty/) doesn't work on file input
 * [#120](https://github.com/nghuuphuoc/bootstrapvalidator/pull/120): Handle case where a field is removed after the bootstrap validation, thanks to [@patmoore](https://github.com/patmoore)
 
 ## v0.3.2 (2014-03-21)
@@ -160,7 +183,7 @@ $(form).bootstrapValidator({
 * [#96](https://github.com/nghuuphuoc/bootstrapvalidator/issues/96): Add [```base64``` validator](http://bootstrapvalidator.com/validators/base64/)
 * [#97](https://github.com/nghuuphuoc/bootstrapvalidator/issues/97): Add [```cvv``` validator](http://bootstrapvalidator.com/validators/cvv/)
 * [#99](https://github.com/nghuuphuoc/bootstrapvalidator/issues/99), [#100](https://github.com/nghuuphuoc/bootstrapvalidator/pull/100): Add [```phone``` validator](http://bootstrapvalidator.com/validators/phone/). Support US phone number only, thanks to [@gercheq](https://github.com/gercheq)
-* [#112](https://github.com/nghuuphuoc/bootstrapvalidator/issues/112): [```creditCard``` validator](http://bootstrapvalidator.com/validators/credit-card/) now validates both IIN ranges and length
+* [#112](https://github.com/nghuuphuoc/bootstrapvalidator/issues/112): [```creditCard``` validator](http://bootstrapvalidator.com/validators/creditCard/) now validates both IIN ranges and length
 
 ## v0.3.1 (2014-03-17)
 
@@ -183,14 +206,14 @@ $(form).bootstrapValidator({
 * [#41](https://github.com/nghuuphuoc/bootstrapvalidator/issues/41): Disable submit button on successful form submit
 * [#42](https://github.com/nghuuphuoc/bootstrapvalidator/issues/42): Add submit button to [```submitHandler()```](http://bootstrapvalidator.com/settings/#submit-handler) parameter
 * [#48](https://github.com/nghuuphuoc/bootstrapvalidator/issues/48): Add optional [feedback icons](http://bootstrapvalidator.com/settings/#feedback-icons)
-* [#64](https://github.com/nghuuphuoc/bootstrapvalidator/pull/64): Support [Danish zip code](http://bootstrapvalidator.com/validators/zip-code/), thanks to [@emilchristensen](https://github.com/emilchristensen)
-* [#65](https://github.com/nghuuphuoc/bootstrapvalidator/pull/65): Support [Sweden zip code](http://bootstrapvalidator.com/validators/zip-code/), thanks to [@emilchristensen](https://github.com/emilchristensen)
+* [#64](https://github.com/nghuuphuoc/bootstrapvalidator/pull/64): Support [Danish zip code](http://bootstrapvalidator.com/validators/zipCode/), thanks to [@emilchristensen](https://github.com/emilchristensen)
+* [#65](https://github.com/nghuuphuoc/bootstrapvalidator/pull/65): Support [Sweden zip code](http://bootstrapvalidator.com/validators/zipCode/), thanks to [@emilchristensen](https://github.com/emilchristensen)
 * [#70](https://github.com/nghuuphuoc/bootstrapvalidator/issues/70): Support custom grid columns
 * [#71](https://github.com/nghuuphuoc/bootstrapvalidator/issues/71): Show all errors
 * [#76](https://github.com/nghuuphuoc/bootstrapvalidator/issues/76): Add [```resetForm()``` method](http://bootstrapvalidator.com/api/#reset-form)
 * [#50](https://github.com/nghuuphuoc/bootstrapvalidator/issues/50): Don't validate disabled element
 * [#51](https://github.com/nghuuphuoc/bootstrapvalidator/issues/51): Submit after submit doesn't work
-* [#53](https://github.com/nghuuphuoc/bootstrapvalidator/issues/53), [#54](https://github.com/nghuuphuoc/bootstrapvalidator/pull/54): Fix [```notEmpty``` validator](http://bootstrapvalidator.com/validators/not-empty/) for radios and checkboxes, thanks to [@kristian-puccio](https://github.com/kristian-puccio)
+* [#53](https://github.com/nghuuphuoc/bootstrapvalidator/issues/53), [#54](https://github.com/nghuuphuoc/bootstrapvalidator/pull/54): Fix [```notEmpty``` validator](http://bootstrapvalidator.com/validators/notEmpty/) for radios and checkboxes, thanks to [@kristian-puccio](https://github.com/kristian-puccio)
 * [#55](https://github.com/nghuuphuoc/bootstrapvalidator/issues/55): The plugin doesn't validate other fields if the [```remote``` validator](http://bootstrapvalidator.com/validators/remote/) returns ```true```
 * [#62](https://github.com/nghuuphuoc/bootstrapvalidator/pull/62): The [```callback``` validator](http://bootstrapvalidator.com/validators/callback/) passes wrong parameter, thanks to [@iplus](https://github.com/iplus)
 * [#59](https://github.com/nghuuphuoc/bootstrapvalidator/pull/59): Add example for Rail field convention, thanks to [@narutosanjiv](https://github.com/narutosanjiv)
@@ -215,7 +238,7 @@ $(form).bootstrapValidator({
 
 * [#24](https://github.com/nghuuphuoc/bootstrapvalidator/issues/24): Add [```live``` option](http://bootstrapvalidator.com/settings/#live)
 * [#20](https://github.com/nghuuphuoc/bootstrapvalidator/issues/20): Add custom submit handler using [```submitHandler``` option](http://bootstrapvalidator.com/settings/#submit-handler)
-* [#9](https://github.com/nghuuphuoc/bootstrapvalidator/issues/9): Add [```creditCard``` validator](http://bootstrapvalidator.com/validators/credit-card/)
+* [#9](https://github.com/nghuuphuoc/bootstrapvalidator/issues/9): Add [```creditCard``` validator](http://bootstrapvalidator.com/validators/creditCard/)
 * [#18](https://github.com/nghuuphuoc/bootstrapvalidator/issues/18): Add [```different``` validator](http://bootstrapvalidator.com/validators/different/)
 * [#21](https://github.com/nghuuphuoc/bootstrapvalidator/issues/21): Add [```callback``` validator](http://bootstrapvalidator.com/validators/callback/)
 * [#22](https://github.com/nghuuphuoc/bootstrapvalidator/issues/22): Support form that labels are placed in extra small (```col-xs-```), small (```col-sm-```), medium (```col-md-```) elements
@@ -234,14 +257,14 @@ $(form).bootstrapValidator({
 * Provide various validators:
     - [```between``` validator](http://bootstrapvalidator.com/validators/between/)
     - [```digits``` validator](http://bootstrapvalidator.com/validators/digits/)
-    - [```emailAddress``` validator](http://bootstrapvalidator.com/validators/email-address/)
-    - [```greaterThan``` validator](http://bootstrapvalidator.com/validators/greater-than/)
-    - [```hexColor``` validator](http://bootstrapvalidator.com/validators/hex-color/)
+    - [```emailAddress``` validator](http://bootstrapvalidator.com/validators/emailAddress/)
+    - [```greaterThan``` validator](http://bootstrapvalidator.com/validators/greaterThan/)
+    - [```hexColor``` validator](http://bootstrapvalidator.com/validators/hexColor/)
     - [```identical``` validator](http://bootstrapvalidator.com/validators/identical/)
-    - [```lessThan``` validator](http://bootstrapvalidator.com/validators/less-than/)
-    - [```notEmpty``` validator](http://bootstrapvalidator.com/validators/not-empty/)
+    - [```lessThan``` validator](http://bootstrapvalidator.com/validators/lessThan/)
+    - [```notEmpty``` validator](http://bootstrapvalidator.com/validators/notEmpty/)
     - [```regexp``` validator](http://bootstrapvalidator.com/validators/regexp/)
     - [```remote``` validator](http://bootstrapvalidator.com/validators/remote/)
-    - [```stringLength``` validator](http://bootstrapvalidator.com/validators/string-length/)
+    - [```stringLength``` validator](http://bootstrapvalidator.com/validators/stringLength/)
     - [```uri``` validator](http://bootstrapvalidator.com/validators/uri/)
-    - [```usZipCode``` validator](http://bootstrapvalidator.com/validators/zip-code/)
+    - [```usZipCode``` validator](http://bootstrapvalidator.com/validators/zipCode/)

+ 6 - 6
README.md

@@ -1,6 +1,6 @@
-# BootstrapValidator - [v0.4.2](https://github.com/nghuuphuoc/bootstrapvalidator/releases/download/v0.4.2/bootstrapvalidator-dist-0.4.2.zip)
+# BootstrapValidator - [v0.4.4](https://github.com/nghuuphuoc/bootstrapvalidator/releases/download/v0.4.4/bootstrapvalidator-dist-0.4.4.zip)
 
-[http://bootstrapvalidator.com](http://bootstrapvalidator.com) - A jQuery plugin to validate form fields. Use with [Bootstrap 3](http://getbootstrap.com)
+[http://bootstrapvalidator.com](http://bootstrapvalidator.com) - The best jQuery plugin to validate form fields. Designed to use with [Bootstrap 3](http://getbootstrap.com)
 
 <a href="https://pledgie.com/campaigns/24885"><img alt="Click here to lend your support to: BootstrapValidator and make a donation at pledgie.com!" src="https://pledgie.com/campaigns/24885.png?skin_name=chrome" border="0" /></a>
 
@@ -28,7 +28,7 @@ __HTML 5__
 * Support [HTML 5 input types](http://bootstrapvalidator.com/examples#html5) such as ```color```, ```email```, ```range``` and ```url```
 
 __Validator__
-* [34 built-in validators](http://bootstrapvalidator.com/validators/) and counting!
+* [41 built-in validators](http://bootstrapvalidator.com/validators/) and counting!
 * Easy to [write a new validator](http://bootstrapvalidator.com/developing/)
  
 __Friendly__
@@ -60,7 +60,7 @@ __Compatibility__
  
 ## Download
 
-Latest version: [v0.4.2 (61 KB)](https://github.com/nghuuphuoc/bootstrapvalidator/releases/download/v0.4.2/bootstrapvalidator-dist-0.4.2.zip), released on 2014-04-19.
+Latest version: [v0.4.4](https://github.com/nghuuphuoc/bootstrapvalidator/releases/download/v0.4.4/bootstrapvalidator-dist-0.4.4.zip), released on 2014-05-05.
 
 For older versions, look at the [Releases](https://github.com/nghuuphuoc/bootstrapvalidator/releases) page.
 
@@ -87,12 +87,12 @@ Big thanks to the contributors:
 * [@emilchristensen](https://github.com/emilchristensen)
 * [@Francismori7](https://github.com/Francismori7)
 * [@gercheq](https://github.com/gercheq)
-* [@khangvm53](https://github.com/khangvm53)
-* [@kristian-puccio](https://github.com/kristian-puccio)
 * [@henningda](https://github.com/henningda)
 * [@ikanedo](https://github.com/ikanedo)
 * [@iplus](https://github.com/iplus)
 * [@jswale](https://github.com/jswale)
+* [@khangvm53](https://github.com/khangvm53)
+* [@kristian-puccio](https://github.com/kristian-puccio)
 * [@narutosanjiv](https://github.com/narutosanjiv)
 * [@patmoore](https://github.com/patmoore)
 * [@tomByrer](https://github.com/tomByrer)

+ 1 - 1
bootstrapValidator.jquery.json

@@ -1,6 +1,6 @@
 {
     "name": "bootstrapValidator",
-    "version": "0.5.0-dev",
+    "version": "0.4.3-dev",
     "title": "BootstrapValidator",
     "author": {
         "name": "Nguyen Huu Phuoc",

+ 1 - 1
bower.json

@@ -1,7 +1,7 @@
 {
     "name": "bootstrapValidator",
     "description": "The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3",
-    "version": "0.5.0-dev",
+    "version": "0.4.3-dev",
     "main": [
         "dist/css/bootstrapValidator.css",
         "dist/js/bootstrapValidator.js"

+ 1 - 1
demo/selector.html

@@ -47,7 +47,7 @@
                         <div class="form-group">
                             <label class="col-lg-3 control-label">CVV</label>
                             <div class="col-lg-2">
-                                <input type="text" class="form-control cvvNumber" />
+                                <input type="text" class="form-control cvvNumber" name="cvv" />
                             </div>
                         </div>
 

+ 135 - 0
demo/tab.html

@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>BootstrapValidator demo</title>
+
+    <link rel="stylesheet" href="../vendor/bootstrap/css/bootstrap.css"/>
+    <link rel="stylesheet" href="../dist/css/bootstrapValidator.css"/>
+
+    <script type="text/javascript" src="../vendor/jquery/jquery-1.10.2.min.js"></script>
+    <script type="text/javascript" src="../vendor/bootstrap/js/bootstrap.min.js"></script>
+    <script type="text/javascript" src="../dist/js/bootstrapValidator.js"></script>
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <section>
+                <div class="col-lg-8 col-lg-offset-2">
+                    <div class="page-header">
+                        <h2>Tab example</h2>
+                    </div>
+
+                    <ul class="nav nav-tabs">
+                        <li class="active"><a href="#info-tab" data-toggle="tab">Information</a></li>
+                        <li><a href="#address-tab" data-toggle="tab">Address</a></li>
+                    </ul>
+
+                    <form id="accountForm" method="post" class="form-horizontal" action="target.php" style="margin-top: 20px;">
+                        <div class="tab-content">
+                            <div class="tab-pane active" id="info-tab">
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">Full name</label>
+                                    <div class="col-lg-5">
+                                        <input type="text" class="form-control" name="fullName" />
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">Company</label>
+                                    <div class="col-lg-5">
+                                        <input type="text" class="form-control" name="company" />
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">Job title</label>
+                                    <div class="col-lg-5">
+                                        <input type="text" class="form-control" name="jobTitle" />
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="tab-pane" id="address-tab">
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">Address</label>
+                                    <div class="col-lg-5">
+                                        <input type="text" class="form-control" name="address" />
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">City</label>
+                                    <div class="col-lg-5">
+                                        <input type="text" class="form-control" name="city" />
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label class="col-lg-3 control-label">Country</label>
+                                    <div class="col-lg-5">
+                                        <select class="form-control" name="country">
+                                            <option value="">Select a country</option>
+                                            <option value="FR">France</option>
+                                            <option value="DE">Germany</option>
+                                            <option value="IT">Italy</option>
+                                            <option value="JP">Japan</option>
+                                            <option value="RU">Russian</option>
+                                            <option value="US">United State</option>
+                                            <option value="GB">United Kingdom</option>
+                                            <option value="other">Other</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <div class="col-lg-5 col-lg-offset-3">
+                                <button type="submit" class="btn btn-primary">Validate</button>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </section>
+        </div>
+    </div>
+
+<script type="text/javascript">
+$(document).ready(function() {
+    $('#accountForm')
+        .bootstrapValidator({
+            excluded: [':disabled'],
+            feedbackIcons: {
+                valid: 'glyphicon glyphicon-ok',
+                invalid: 'glyphicon glyphicon-remove',
+                validating: 'glyphicon glyphicon-refresh'
+            },
+            fields: {
+                fullName: {
+                    validators: {
+                        notEmpty: {
+                            message: 'The full name is required'
+                        }
+                    }
+                },
+                company: {
+                    validators: {
+                        notEmpty: {
+                            message: 'The company name is required'
+                        }
+                    }
+                },
+                address: {
+                    validators: {
+                        notEmpty: {
+                            message: 'The address is required'
+                        }
+                    }
+                },
+                city: {
+                    validators: {
+                        notEmpty: {
+                            message: 'The city is required'
+                        }
+                    }
+                }
+            }
+        });
+});
+</script>
+</body>
+</html>

+ 7 - 1
dist/css/bootstrapValidator.css

@@ -8,6 +8,12 @@
  * @license     MIT
  */
 
-.bootstrap-validator-form .help-block {
+.bv-form .help-block {
     margin-bottom: 0;
 }
+.nav-tabs li.bv-tab-success > a {
+    color: #3c763d;
+}
+.nav-tabs li.bv-tab-error > a {
+    color: #a94442;
+}

+ 2 - 2
dist/css/bootstrapValidator.min.css

@@ -3,11 +3,11 @@
  *
  * A jQuery plugin to validate form fields. Use with Bootstrap 3
  *
- * @version     v0.5.0-dev
+ * @version     v0.4.5-dev
  * @author      https://twitter.com/nghuuphuoc
  * @copyright   (c) 2013 - 2014 Nguyen Huu Phuoc
  * @license     MIT
  */
 
 
-.bootstrap-validator-form .help-block{margin-bottom:0}
+.bv-form .help-block{margin-bottom:0}.nav-tabs li.bv-tab-success>a{color:#3c763d}.nav-tabs li.bv-tab-error>a{color:#a94442}

File diff suppressed because it is too large
+ 856 - 385
dist/js/bootstrapValidator.js


File diff suppressed because it is too large
+ 3 - 3
dist/js/bootstrapValidator.min.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
     "name": "bootstrapValidator",
-    "version": "0.5.0-dev",
+    "version": "0.4.3-dev",
     "description": "The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3",
     "keywords": ["jQuery", "plugin", "validate", "validator", "form", "Bootstrap"],
     "author": {

+ 7 - 1
src/css/bootstrapValidator.css

@@ -8,6 +8,12 @@
  * @license     MIT
  */
 
-.bootstrap-validator-form .help-block {
+.bv-form .help-block {
     margin-bottom: 0;
 }
+.nav-tabs li.bv-tab-success > a {
+    color: #3c763d;
+}
+.nav-tabs li.bv-tab-error > a {
+    color: #a94442;
+}

+ 110 - 32
src/js/bootstrapValidator.js

@@ -25,9 +25,16 @@
         // Determine the event that is fired when user change the field value
         // Most modern browsers supports input event except IE 7, 8.
         // IE 9 supports input event but the event is still not fired if I press the backspace key.
-        // In that case I will use the keydown event
+        // Get IE version
+        // https://gist.github.com/padolsey/527683/#comment-7595
+        var ieVersion = (function() {
+            var v = 3, div = document.createElement('div'), a = div.all || [];
+            while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]);
+            return v > 4 ? v : !v;
+        }());
+
         var el = document.createElement('div');
-        this._changeEvent = ('oninput' in el) ? 'input' : 'keydown';
+        this._changeEvent = (ieVersion === 9 || !('oninput' in el)) ? 'keyup' : 'input';
 
         // The flag to indicate that the form is ready to submit when a remote/callback validator returns
         this._submitIfValid = null;
@@ -41,11 +48,14 @@
     // The default options
     BootstrapValidator.DEFAULT_OPTIONS = {
         // The form CSS class
-        elementClass: 'bootstrap-validator-form',
+        elementClass: 'bv-form',
 
         // Default invalid message
         message: 'This value is not valid',
 
+        // The field will not be live validated if its length is less than this number of characters
+        threshold: null,
+
         // Indicate fields which won't be validated
         // By default, the plugin will not validate the following kind of fields:
         // - disabled
@@ -132,6 +142,7 @@
                     trigger:        this.$form.attr('data-bv-trigger'),
                     message:        this.$form.attr('data-bv-message'),
                     submitButtons:  this.$form.attr('data-bv-submitbuttons'),
+                    threshold:      this.$form.attr('data-bv-threshold'),
                     live:           this.$form.attr('data-bv-live'),
                     fields:         {},
                     feedbackIcons: {
@@ -165,22 +176,12 @@
                 // Find all fields which have either "name" or "data-bv-field" attribute
                 .find('[name], [data-bv-field]').each(function() {
                     var $field = $(this);
-                    // Don't initialize hidden input
-                    if ('hidden' == $field.attr('type')) {
+                    if (that._isExcluded($field)) {
                         return;
                     }
 
-                    var field  = $field.attr('name') || $field.attr('data-bv-field');
-                    $field.attr('data-bv-field', field);
-
-                    options.fields[field] = $.extend({}, {
-                        trigger:    $field.attr('data-bv-trigger'),
-                        message:    $field.attr('data-bv-message'),
-                        container:  $field.attr('data-bv-container'),
-                        selector:   $field.attr('data-bv-selector'),
-                        validators: {}
-                    }, options.fields[field]);
-
+                    var field      = $field.attr('name') || $field.attr('data-bv-field'),
+                        validators = {};
                     for (v in $.fn.bootstrapValidator.validators) {
                         validator  = $.fn.bootstrapValidator.validators[v];
                         enabled    = $field.attr('data-bv-' + v.toLowerCase()) + '';
@@ -191,7 +192,7 @@
                         {
                             // Try to parse the options via attributes
                             validator.html5Attributes = validator.html5Attributes || { message: 'message' };
-                            options.fields[field]['validators'][v] = $.extend({}, html5Attrs == true ? {} : html5Attrs, options.fields[field]['validators'][v]);
+                            validators[v] = $.extend({}, html5Attrs == true ? {} : html5Attrs, validators[v]);
 
                             for (html5AttrName in validator.html5Attributes) {
                                 optionName  = validator.html5Attributes[html5AttrName];
@@ -202,11 +203,26 @@
                                     } else if ('false' == optionValue) {
                                         optionValue = false;
                                     }
-                                    options.fields[field]['validators'][v][optionName] = optionValue;
+                                    validators[v][optionName] = optionValue;
                                 }
                             }
                         }
                     }
+
+                    var opts = {
+                        trigger:    $field.attr('data-bv-trigger'),
+                        message:    $field.attr('data-bv-message'),
+                        container:  $field.attr('data-bv-container'),
+                        selector:   $field.attr('data-bv-selector'),
+                        threshold:  $field.attr('data-bv-threshold'),
+                        validators: validators
+                    };
+
+                    // Check if there is any validators set using HTML attributes
+                    if (!$.isEmptyObject(opts)) {
+                        $field.attr('data-bv-field', field);
+                        options.fields[field] = $.extend({}, opts, options.fields[field]);
+                    }
                 });
 
             this.options = $.extend(true, this.options, options);
@@ -220,6 +236,8 @@
             for (var field in this.options.fields) {
                 this._initField(field);
             }
+
+            this.setLiveMode(this.options.live);
         },
 
         /**
@@ -397,7 +415,7 @@
 
             return false;
         },
-
+        
         // --- Events ---
 
         /**
@@ -630,13 +648,12 @@
          * @return {BootstrapValidator}
          */
         updateElementStatus: function($field, status, validatorName) {
-            var that       = this,
-                field      = $field.attr('data-bv-field'),
-                $parent    = $field.parents('.form-group'),
-                $message   = $field.data('bv.messages'),
-                $rowErrors = $parent.find('.help-block[data-bv-validator]'),
-                $errors    = $message.find('.help-block[data-bv-validator]'),
-                $icon      = $parent.find('.form-control-feedback[data-bv-field="' + field + '"]');
+            var that     = this,
+                field    = $field.attr('data-bv-field'),
+                $parent  = $field.parents('.form-group'),
+                $message = $field.data('bv.messages'),
+                $errors  = $message.find('.help-block[data-bv-validator]'),
+                $icon    = $parent.find('.form-control-feedback[data-bv-field="' + field + '"]');
 
             // Update status
             if (validatorName) {
@@ -647,6 +664,14 @@
                 }
             }
 
+            // Determine the tab containing the element
+            var $tabPane = $field.parents('.tab-pane'),
+                tabId,
+                $tab;
+            if ($tabPane && (tabId = $tabPane.attr('id'))) {
+                $tab = $('a[href="#' + tabId + '"][data-toggle="tab"]').parent();
+            }
+
             // Show/hide error elements and feedback icons
             switch (status) {
                 case this.STATUS_VALIDATING:
@@ -657,6 +682,9 @@
                     if ($icon) {
                         $icon.removeClass(this.options.feedbackIcons.valid).removeClass(this.options.feedbackIcons.invalid).addClass(this.options.feedbackIcons.validating).show();
                     }
+                    if ($tab) {
+                        $tab.removeClass('bv-tab-success').removeClass('bv-tab-error');
+                    }
                     break;
 
                 case this.STATUS_INVALID:
@@ -666,6 +694,9 @@
                     if ($icon) {
                         $icon.removeClass(this.options.feedbackIcons.valid).removeClass(this.options.feedbackIcons.validating).addClass(this.options.feedbackIcons.invalid).show();
                     }
+                    if ($tab) {
+                        $tab.removeClass('bv-tab-success').addClass('bv-tab-error');
+                    }
                     break;
 
                 case this.STATUS_VALID:
@@ -684,12 +715,20 @@
                             .show();
                     }
 
-                    // Check if all fields in the same row are valid
-                    var validRow = ($rowErrors.filter(function() {
+                    // Check if all elements in given container are valid
+                    var isValidContainer = function($container) {
+                        return $container
+                                    .find('.help-block[data-bv-validator]')
+                                    .filter(function() {
                                         var display = $(this).css('display'), v = $(this).attr('data-bv-validator');
-                                        return ('block' == display) || ($field.data('bv.result.' + v) != that.STATUS_VALID);
-                                    }).length == 0);
-                    $parent.removeClass('has-error has-success').addClass(validRow ? 'has-success' : 'has-error');
+                                        return ('block' == display) || ($field.data('bv.result.' + v) && $field.data('bv.result.' + v) != that.STATUS_VALID);
+                                    })
+                                    .length == 0;
+                    };
+                    $parent.removeClass('has-error has-success').addClass(isValidContainer($parent) ? 'has-success' : 'has-error');
+                    if ($tab) {
+                        $tab.removeClass('bv-tab-success').removeClass('bv-tab-error').addClass(isValidContainer($tabPane) ? 'bv-tab-success' : 'bv-tab-error');
+                    }
                     break;
 
                 case this.STATUS_NOT_VALIDATED:
@@ -700,6 +739,9 @@
                     if ($icon) {
                         $icon.removeClass(this.options.feedbackIcons.valid).removeClass(this.options.feedbackIcons.invalid).removeClass(this.options.feedbackIcons.validating).hide();
                     }
+                    if ($tab) {
+                        $tab.removeClass('bv-tab-success').removeClass('bv-tab-error');
+                    }
                     break;
             }
 
@@ -886,7 +928,7 @@
          * Credit to https://gist.github.com/ShirtlessKirk/2134376
          *
          * @param {String} value
-         * @returns {boolean}
+         * @returns {Boolean}
          */
         luhn: function(value) {
             var length  = value.length,
@@ -900,6 +942,42 @@
             }
 
             return (sum % 10 === 0 && sum > 0);
+        },
+
+        /**
+         * Implement modulus 11, 10 (ISO 7064) algorithm
+         *
+         * @param {String} value
+         * @returns {Boolean}
+         */
+        mod_11_10: function(value) {
+            var check  = 5,
+                length = value.length;
+            for (var i = 0; i < length; i++) {
+                check = (((check || 10) * 2) % 11 + parseInt(value.charAt(i), 10)) % 10;
+            }
+            return (check == 1);
+        },
+
+        /**
+         * Implements Mod 37, 36 (ISO 7064) algorithm
+         * Usages:
+         * mod_37_36('A12425GABC1234002M')
+         * mod_37_36('002006673085', '0123456789')
+         *
+         * @param {String} value
+         * @param {String} alphabet
+         * @returns {Boolean}
+         */
+        mod_37_36: function(value, alphabet) {
+            alphabet = alphabet || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+            var modulus = alphabet.length,
+                length  = value.length,
+                check   = Math.floor(modulus / 2);
+            for (var i = 0; i < length; i++) {
+                check = (((check || modulus) * 2) % (modulus + 1) + alphabet.indexOf(value.charAt(i))) % modulus;
+            }
+            return (check == 1);
         }
     };
 }(window.jQuery));

+ 1 - 1
src/js/validator/creditCard.js

@@ -55,7 +55,7 @@
                 },
                 LASER: {
                     length: [16, 17, 18, 19],
-                    prefix: ['3528', '3529', '353', '354', '355', '356', '357', '358']
+                    prefix: ['6304', '6706', '6771', '6709']
                 },
                 MAESTRO: {
                     length: [12, 13, 14, 15, 16, 17, 18, 19],

+ 1 - 1
src/js/validator/cvv.js

@@ -64,7 +64,7 @@
                 },
                 LASER: {
                     length: [16, 17, 18, 19],
-                    prefix: ['3528', '3529', '353', '354', '355', '356', '357', '358']
+                    prefix: ['6304', '6706', '6771', '6709']
                 },
                 MAESTRO: {
                     length: [12, 13, 14, 15, 16, 17, 18, 19],

+ 63 - 74
src/js/validator/date.js

@@ -11,28 +11,14 @@
          * @param {BootstrapValidator} validator The validator plugin instance
          * @param {jQuery} $field Field element
          * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
          * - format: The date format. Default is MM/DD/YYYY
-         * Support the following formats:
-         *      YYYY/DD/MM
-         *      YYYY/DD/MM h:m A
-         *      YYYY/MM/DD
-         *      YYYY/MM/DD h:m A
-         *
-         *      YYYY-DD-MM
-         *      YYYY-DD-MM h:m A
-         *      YYYY-MM-DD
-         *      YYYY-MM-DD h:m A
-         *
-         *      MM/DD/YYYY
-         *      MM/DD/YYYY h:m A
-         *      DD/MM/YYYY
-         *      DD/MM/YYYY h:m A
+         * The format can be:
          *
-         *      MM-DD-YYYY
-         *      MM-DD-YYYY h:m A
-         *      DD-MM-YYYY
-         *      DD-MM-YYYY h:m A
-         * - message: The invalid message
+         * i) date: Consist of DD, MM, YYYY parts which are separated by /
+         * ii) date and time:
+         * The time can consist of h, m, s parts which are separated by :
+         * ii) date, time and A (indicating AM or PM)
          * @returns {Boolean}
          */
         validate: function(validator, $field, options) {
@@ -40,68 +26,71 @@
             if (value == '') {
                 return true;
             }
-            // Determine the separator
+
             options.format = options.format || 'MM/DD/YYYY';
-            var separator = (options.format.indexOf('/') != -1)
-                            ? '/'
-                            : ((options.format.indexOf('-') != -1) ? '-' : null);
-            if (separator == null) {
+
+            var formats    = options.format.split(' '),
+                dateFormat = formats[0],
+                timeFormat = (formats.length > 1) ? formats[1] : null,
+                amOrPm     = (formats.length > 2) ? formats[2] : null,
+                sections   = value.split(' '),
+                date       = sections[0],
+                time       = (sections.length > 1) ? sections[1] : null;
+
+            if (formats.length != sections.length) {
                 return false;
             }
 
-            var month, day, year, minutes = null, hours = null, matches;
-            switch (true) {
-                case (separator == '/' && (matches = value.match(/^(\d{4})\/(\d{1,2})\/(\d{1,2})$/i)) && options.format == 'YYYY/DD/MM'):
-                case (separator == '-' && (matches = value.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/i)) && options.format == 'YYYY-DD-MM'):
-                    year = matches[1]; day = matches[2]; month = matches[3];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/i)) && options.format == 'DD/MM/YYYY'):
-                case (separator == '-' && (matches = value.match(/^(\d{1,2})-(\d{1,2})-(\d{4})$/i)) && options.format == 'DD-MM-YYYY'):
-                    day = matches[1]; month = matches[2]; year = matches[3];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{4})\/(\d{1,2})\/(\d{1,2})$/i)) && options.format == 'YYYY/MM/DD'):
-                case (separator == '-' && (matches = value.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/i)) && options.format == 'YYYY-MM-DD'):
-                    year = matches[1]; month = matches[2]; day = matches[3];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/i)) && options.format == 'MM/DD/YYYY'):
-                case (separator == '-' && (matches = value.match(/^(\d{1,2})-(\d{1,2})-(\d{4})$/i)) && options.format == 'MM-DD-YYYY'):
-                    month = matches[1]; day = matches[2]; year = matches[3];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{4})\/(\d{1,2})\/(\d{1,2})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'YYYY/DD/MM h:m A'):
-                case (separator == '-' && (matches = value.match(/^(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'YYYY-DD-MM h:m A'):
-                    year = matches[1]; day = matches[2]; month = matches[3]; hours = matches[4]; minutes = matches[5];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'DD/MM/YYYY h:m A'):
-                case (separator == '-' && (matches = value.match(/^(\d{1,2})-(\d{1,2})-(\d{4})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'DD-MM-YYYY h:m A'):
-                    day = matches[1]; month = matches[2]; year = matches[3]; hours = matches[4]; minutes = matches[5];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{4})\/(\d{1,2})\/(\d{1,2})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'YYYY/MM/DD h:m A'):
-                case (separator == '-' && (matches = value.match(/^(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'YYYY-MM-DD h:m A'):
-                    year = matches[1]; month = matches[2]; day = matches[3]; hours = matches[4]; minutes = matches[5];
-                    break;
-
-                case (separator == '/' && (matches = value.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'MM/DD/YYYY h:m A'):
-                case (separator == '-' && (matches = value.match(/^(\d{1,2})-(\d{1,2})-(\d{4})\s+(\d{1,2}):(\d{1,2})\s+(AM|PM)$/i)) && options.format == 'MM-DD-YYYY h:m A'):
-                    month = matches[1]; day = matches[2]; year = matches[3]; hours = matches[4]; minutes = matches[5];
-                    break;
-
-                default:
-                    return false;
+            // Determine the separator
+            var separator = (date.indexOf('/') != -1) ? '/' : ((date.indexOf('-') != -1) ? '-' : null);
+            if (separator == null) {
+                return false;
             }
 
-            // Validate hours and minutes
-            if (hours && minutes) {
-                hours   = parseInt(hours, 10);
-                minutes = parseInt(minutes, 10);
-                if (hours < 1 || hours > 12 || minutes < 0 || minutes > 59) {
+            // Determine the date
+            date       = date.split(separator);
+            dateFormat = dateFormat.split(separator);
+            var year  = date[dateFormat.indexOf('YYYY')],
+                month = date[dateFormat.indexOf('MM')],
+                day   = date[dateFormat.indexOf('DD')];
+
+            // Determine the time
+            var minutes = null, hours = null, seconds = null;
+            if (timeFormat) {
+                timeFormat = timeFormat.split(':'),
+                time       = time.split(':');
+
+                if (timeFormat.length != time.length) {
                     return false;
                 }
+
+                hours   = time.length > 0 ? time[0] : null;
+                minutes = time.length > 1 ? time[1] : null;
+                seconds = time.length > 2 ? time[2] : null;
+
+                // Validate seconds
+                if (seconds) {
+                    seconds = parseInt(seconds, 10);
+                    if (seconds < 0 || seconds > 60) {
+                        return false;
+                    }
+                }
+
+                // Validate hours
+                if (hours) {
+                    hours = parseInt(hours, 10);
+                    if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
+                        return false;
+                    }
+                }
+
+                // Validate minutes
+                if (minutes) {
+                    minutes = parseInt(minutes, 10);
+                    if (minutes < 0 || minutes > 59) {
+                        return false;
+                    }
+                }
             }
 
             // Validate day, month, and year

+ 36 - 0
src/js/validator/ean.js

@@ -0,0 +1,36 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.ean = {
+        /**
+         * Validate EAN (International Article Number)
+         * Examples:
+         * - Valid: 73513537, 9780471117094, 4006381333931
+         * - Invalid: 73513536
+         *
+         * @see http://en.wikipedia.org/wiki/European_Article_Number
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            if (!/^(\d{8}|\d{12}|\d{13})$/.test(value)) {
+                return false;
+            }
+
+            var length = value.length,
+                sum    = 0,
+                weight = (length == 8) ? [3, 1] : [1, 3];
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i)) * weight[i % 2];
+            }
+            sum = 10 - sum % 10;
+            return (sum == value.charAt(length - 1));
+        }
+    };
+}(window.jQuery));

+ 33 - 0
src/js/validator/grid.js

@@ -0,0 +1,33 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.grid = {
+        /**
+         * Validate GRId (Global Release Identifier)
+         * Examples:
+         * - Valid: A12425GABC1234002M, A1-2425G-ABC1234002-M, A1 2425G ABC1234002 M, Grid:A1-2425G-ABC1234002-M
+         * - Invalid: A1-2425G-ABC1234002-Q
+         *
+         * @see http://en.wikipedia.org/wiki/Global_Release_Identifier
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            value = value.toUpperCase();
+            if (!/^[GRID:]*([0-9A-Z]{2})[-\s]*([0-9A-Z]{5})[-\s]*([0-9A-Z]{10})[-\s]*([0-9A-Z]{1})$/g.test(value)) {
+                return false;
+            }
+            value = value.replace(/\s/g, '').replace(/-/g, '');
+            if ('GRID:' == value.substr(0, 5)) {
+                value = value.substr(5);
+            }
+            return $.fn.bootstrapValidator.helpers.mod_37_36(value);
+        }
+    };
+}(window.jQuery));

+ 199 - 0
src/js/validator/id.js

@@ -0,0 +1,199 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.id = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country'
+        },
+
+        /**
+         * Validate identification number in different countries
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - country: The ISO 3166-1 country code
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            var country = options.country || value.substr(0, 2),
+                method  = ['_', country.toLowerCase()].join('');
+            if (this[method] && 'function' == typeof this[method]) {
+                return this[method](value);
+            }
+
+            return true;
+        },
+
+        /**
+         * Validate Bulgarian national identification number (EGN)
+         * Examples:
+         * - Valid: 7523169263, 8032056031, 803205 603 1, 8001010008, 7501020018, 7552010005, 7542011030
+         * - Invalid: 8019010008
+         *
+         * @see http://en.wikipedia.org/wiki/Uniform_civil_number
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _bg: function(value) {
+            if (!/^\d{10}$/.test(value) && !/^\d{6}\s\d{3}\s\d{1}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\s/g, '');
+            // Check the birth date
+            var year  = parseInt(value.substr(0, 2), 10) + 1900,
+                month = parseInt(value.substr(2, 2), 10),
+                day   = parseInt(value.substr(4, 2), 10);
+            if (month > 40) {
+                year += 100;
+                month -= 40;
+            } else if (month > 20) {
+                year -= 100;
+                month -= 20;
+            }
+
+            try {
+                var d = new Date(year, month, day);
+            } catch (ex) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [2, 4, 8, 5, 10, 9, 7, 3, 6];
+            for (var i = 0; i < 9; i++) {
+                sum += parseInt(value.charAt(i)) * weight[i];
+            }
+            sum = (sum % 11) % 10;
+            return (sum == value.substr(9, 1));
+        },
+
+        /**
+         * Validate Brazilian national identification number (CPF)
+         * Examples:
+         * - Valid: 39053344705, 390.533.447-05, 111.444.777-35
+         * - Invalid: 231.002.999-00
+         *
+         * @see http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _br: function(value) {
+            if (/^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) {
+                return false;
+            }
+            if (!/^\d{11}$/.test(value) && !/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\./g, '').replace(/-/g, '');
+
+            var d1 = 0;
+            for (var i = 0; i < 9; i++) {
+                d1 += (10 - i) * parseInt(value.charAt(i));
+            }
+            d1 = 11 - d1 % 11;
+            if (d1 == 10 || d1 == 11) {
+                d1 = 0;
+            }
+            if (d1 != value.charAt(9)) {
+                return false;
+            }
+
+            var d2 = 0;
+            for (i = 0; i < 10; i++) {
+                d2 += (11 - i) * parseInt(value.charAt(i));
+            }
+            d2 = 11 - d2 % 11;
+            if (d2 == 10 || d2 == 11) {
+                d2 = 0;
+            }
+
+            return (d2 == value.charAt(10));
+        },
+
+        /**
+         * Validate Czech national identification number (RC)
+         * Examples:
+         * - Valid: 7103192745, 991231123
+         * - Invalid: 1103492745, 590312123
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _cz: function(value) {
+            if (!/^\d{9,10}$/.test(value)) {
+                return false;
+            }
+            var year  = 1900 + parseInt(value.substr(0, 2)),
+                month = parseInt(value.substr(2, 2)) % 50 % 20,
+                day   = parseInt(value.substr(4, 2));
+            if (value.length == 9) {
+                if (year >= 1980) {
+                    year -= 100;
+                }
+                if (year > 1953) {
+                    return false;
+                }
+            } else if (year < 1954) {
+                year += 100;
+            }
+
+            try {
+                var d = new Date(year, month, day);
+            } catch (ex) {
+                return false;
+            }
+
+            // Check that the birth date is not in the future
+            if (value.length == 10) {
+                var check = parseInt(value.substr(0, 9), 10) % 11;
+                if (year < 1985) {
+                    check = check % 10;
+                }
+                return (check == value.substr(9, 1));
+            }
+
+            return true;
+        },
+
+        /**
+         * Validate Spanish personal identity code (DNI)
+         * Examples:
+         * - Valid: 54362315K, 54362315-K
+         * - Invalid: 54362315Z
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _es: function(value) {
+            if (!/^[0-9A-Z]{8}[-]{0,1}[0-9A-Z]{1}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/-/g, '');
+            var check = parseInt(value.substr(0, 8), 10);
+            check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
+            return (check == value.substr(8, 1));
+        },
+
+        /**
+         * Validate Croatian personal identification number (OIB)
+         * Examples:
+         * - Valid: 33392005961
+         * - Invalid: 33392005962
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _hr: function(value) {
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+            return $.fn.bootstrapValidator.helpers.mod_11_10(value);
+        }
+    };
+}(window.jQuery));

+ 41 - 0
src/js/validator/imei.js

@@ -0,0 +1,41 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.imei = {
+        /**
+         * Validate IMEI (International Mobile Station Equipment Identity)
+         * Examples:
+         * - Valid: 35-209900-176148-1, 35-209900-176148-23, 3568680000414120, 490154203237518
+         * - Invalid: 490154203237517
+         *
+         * @see http://en.wikipedia.org/wiki/International_Mobile_Station_Equipment_Identity
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            switch (true) {
+                case /^\d{15}$/.test(value):
+                case /^\d{2}-\d{6}-\d{6}-\d{1}$/.test(value):
+                case /^\d{2}\s\d{6}\s\d{6}\s\d{1}$/.test(value):
+                    value = value.replace(/[^0-9]/g, '');
+                    return $.fn.bootstrapValidator.helpers.luhn(value);
+                    break;
+
+                case /^\d{14}$/.test(value):
+                case /^\d{16}$/.test(value):
+                case /^\d{2}-\d{6}-\d{6}(|-\d{2})$/.test(value):
+                case /^\d{2}\s\d{6}\s\d{6}(|\s\d{2})$/.test(value):
+                    return true;
+
+                default:
+                    return false;
+            }
+        }
+    };
+}(window.jQuery));

+ 1 - 0
src/js/validator/isbn.js

@@ -10,6 +10,7 @@
          * ISBN 10: 99921-58-10-6
          * ISBN 13: 978-0-306-40615-6
          *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
          * @param {BootstrapValidator} validator The validator plugin instance
          * @param {jQuery} $field Field element
          * @param {Object} options Can consist of the following keys:

+ 55 - 0
src/js/validator/ismn.js

@@ -0,0 +1,55 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.ismn = {
+        /**
+         * Validate ISMN (International Standard Music Number)
+         * Examples:
+         * - Valid: M230671187, 979-0-0601-1561-5, 979 0 3452 4680 5, 9790060115615
+         * - Invalid: 9790060115614
+         *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Music_Number
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            // Groups are separated by a hyphen or a space
+            var type;
+            switch (true) {
+                case /^M\d{9}$/.test(value):
+                case /^M-\d{4}-\d{4}-\d{1}$/.test(value):
+                case /^M\s\d{4}\s\d{4}\s\d{1}$/.test(value):
+                    type = 'ISMN10';
+                    break;
+                case /^9790\d{9}$/.test(value):
+                case /^979-0-\d{4}-\d{4}-\d{1}$/.test(value):
+                case /^979\s0\s\d{4}\s\d{4}\s\d{1}$/.test(value):
+                    type = 'ISMN13';
+                    break;
+                default:
+                    return false;
+            }
+
+            if ('ISMN10' == type) {
+                value = '9790' + value.substr(1);
+            }
+
+            // Replace all special characters except digits
+            value = value.replace(/[^0-9]/gi, '');
+            var length = value.length,
+                sum    = 0,
+                weight = [1, 3];
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i)) * weight[i % 2];
+            }
+            sum = 10 - sum % 10;
+            return (sum == value.charAt(length - 1));
+        }
+    };
+}(window.jQuery));

+ 42 - 0
src/js/validator/issn.js

@@ -0,0 +1,42 @@
+(function($) {
+    $.fn.bootstrapValidator.validators.issn = {
+        /**
+         * Validate ISSN (International Standard Serial Number)
+         * Examples:
+         * - Valid: 0378-5955, 0024-9319, 0032-1478
+         * - Invalid: 0032-147X
+         *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Serial_Number
+         * @param {BootstrapValidator} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options) {
+            var value = $field.val();
+            if (value == '') {
+                return true;
+            }
+
+            // Groups are separated by a hyphen or a space
+            if (!/^\d{4}\-\d{3}[\dX]$/.test(value)) {
+                return false;
+            }
+
+            // Replace all special characters except digits and X
+            value = value.replace(/[^0-9X]/gi, '');
+            var chars  = value.split(''),
+                length = chars.length,
+                sum    = 0;
+
+            if (chars[7] == 'X') {
+                chars[7] = 10;
+            }
+            for (var i = 0; i < length; i++) {
+                sum += ((8 - i) * parseInt(chars[i]));
+            }
+            return (sum % 11 == 0);
+        }
+    };
+}(window.jQuery));

+ 80 - 54
src/js/validator/vat.js

@@ -17,7 +17,7 @@
          */
         validate: function(validator, $field, options) {
             var value = $field.val();
-            if (value == '' || !options.country) {
+            if (value == '') {
                 return true;
             }
 
@@ -281,7 +281,8 @@
 
             value = value.substr(2);
 
-            var sum = 0, weight = [], i = 0;
+            var sum = 0,
+                i   = 0;
             if (value.length == 8) {
                 // Do not allow to start with '9'
                 if (value.charAt(0) + '' == '9') {
@@ -289,7 +290,7 @@
                 }
 
                 sum = 0;
-                for (var i = 0; i < 7; i++) {
+                for (i = 0; i < 7; i++) {
                     sum += parseInt(value.charAt(i), 10) * (8 - i);
                 }
                 sum = 11 - sum % 11;
@@ -304,7 +305,7 @@
             } else if (value.length == 9 && (value.charAt(0) + '' == '6')) {
                 sum = 0;
                 // Skip the first (which is 6)
-                for (var i = 0; i < 7; i++) {
+                for (i = 0; i < 7; i++) {
                     sum += parseInt(value.charAt(i + 1), 10) * (8 - i);
                 }
                 sum = 11 - sum % 11;
@@ -318,38 +319,36 @@
                 return (sum == value.substr(8, 1));
             } else if (value.length == 9 || value.length == 10) {
                 // Validate Czech birth number (Rodné číslo), which is also national identifier
-                var rc = function(value) {
-                    var year  = 1900 + parseInt(value.substr(0, 2)),
-                        month = parseInt(value.substr(2, 2)) % 50 % 20,
-                        day   = parseInt(value.substr(4, 2));
-                    if (value.length == 9) {
-                        if (year >= 1980) {
-                            year -= 100;
-                        }
-                        if (year > 1953) {
-                            return false;
-                        }
-                    } else if (year < 1954) {
-                        year += 100;
+                var year  = 1900 + parseInt(value.substr(0, 2)),
+                    month = parseInt(value.substr(2, 2)) % 50 % 20,
+                    day   = parseInt(value.substr(4, 2));
+                if (value.length == 9) {
+                    if (year >= 1980) {
+                        year -= 100;
                     }
-
-                    try {
-                        var d = new Date(year, month, day);
-                    } catch (ex) {
+                    if (year > 1953) {
                         return false;
                     }
+                } else if (year < 1954) {
+                    year += 100;
+                }
 
-                    // Check that the birth date is not in the future
-                    if (value.length == 10) {
-                        var check = parseInt(value.substr(0, 9), 10) % 11;
-                        if (year < 1985) {
-                            check = check % 10;
-                        }
-                        return (check == value.substr(9, 1));
+                try {
+                    var d = new Date(year, month, day);
+                } catch (ex) {
+                    return false;
+                }
+
+                // Check that the birth date is not in the future
+                if (value.length == 10) {
+                    var check = parseInt(value.substr(0, 9), 10) % 11;
+                    if (year < 1985) {
+                        check = check % 10;
                     }
+                    return (check == value.substr(9, 1));
+                }
 
-                    return true;
-                };
+                return true;
             }
 
             return false;
@@ -370,18 +369,7 @@
             }
 
             value = value.substr(2);
-            var product = 10,
-                sum     = 0;
-            for (var i = 0; i < 8; i++) {
-                sum = (parseInt(value.charAt(i), 10) + product) % 10;
-                if (sum == 0) {
-                    sum = 10;
-                }
-                product = (sum * 2) % 11;
-            }
-
-            var checkDigit = (11 - product == 10) ? 0 : (11 - product);
-            return (checkDigit == value.substr(8, 1));
+            return $.fn.bootstrapValidator.helpers.mod_11_10(value);
         },
 
         /**
@@ -695,18 +683,7 @@
             }
 
             value = value.substr(2);
-            var sum  = 10,
-                temp = 0;
-
-            for (var i = 0; i < 10; i++) {
-                temp = (parseInt(value.charAt(i), 10) + sum) % 10;
-                if (temp == 0) {
-                    temp = 10;
-                }
-                sum = (temp * 2) % 11;
-            }
-            sum += parseInt(value.substr(10, 1), 10);
-            return (sum % 10 == 1);
+            return $.fn.bootstrapValidator.helpers.mod_11_10(value);
         },
 
         /**
@@ -1045,6 +1022,55 @@
         },
 
         /**
+         * Validate Russian VAT number (Taxpayer Identification Number - INN)
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ru: function(value) {
+            if (!/^RU([0-9]{9}|[0-9]{12})$/.test(value)) {
+                return false;
+            }
+
+            value = value.substr(2);
+            if (value.length == 10) {
+                var sum    = 0,
+                    weight = [2, 4, 10, 3, 5, 9, 4, 6, 8, 0];
+                for (var i = 0; i < 10; i++) {
+                    sum += parseInt(value.charAt(i)) * weight[i];
+                }
+                sum = sum % 11;
+                if (sum > 9) {
+                    sum = sum % 10;
+                }
+
+                return (sum == value.substr(9, 1));
+            } else if (value.length == 12) {
+                var sum1    = 0,
+                    weight1 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0],
+                    sum2    = 0,
+                    weight2 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0];
+
+                for (var i = 0; i < 11; i++) {
+                    sum1 += parseInt(value.charAt(i)) * weight1[i];
+                    sum2 += parseInt(value.charAt(i)) * weight2[i];
+                }
+                sum1 = sum1 % 11;
+                if (sum1 > 9) {
+                    sum1 = sum1 % 10;
+                }
+                sum2 = sum2 % 11;
+                if (sum2 > 9) {
+                    sum2 = sum2 % 10;
+                }
+
+                return (sum1 == value.substr(10, 1) && sum2 == value.substr(11, 1));
+            }
+
+            return false;
+        },
+
+        /**
          * Validate Serbian VAT number
          *
          * @param {String} value VAT number

+ 44 - 0
src/js/validator/zipCode.js

@@ -18,6 +18,7 @@
          * - US (United State)
          * - CA (Canada)
          * - DK (Denmark)
+         * - GB (United Kingdom)
          * - SE (Sweden)
          * @returns {Boolean}
          */
@@ -33,12 +34,55 @@
                     return /(?:A|B|C|E|G|J|K|L|M|N|P|R|S|T|V|X|Y){1}[0-9]{1}(?:A|B|C|E|G|J|K|L|M|N|P|R|S|T|V|X|Y){1}\s?[0-9]{1}(?:A|B|C|E|G|J|K|L|M|N|P|R|S|T|V|X|Y){1}[0-9]{1}/i.test(value);
                 case 'DK':
                     return /^(DK(-|\s)?)?\d{4}$/i.test(value);
+                case 'GB':
+                    return this._gb(value);
                 case 'SE':
                     return /^(S-)?\d{3}\s?\d{2}$/i.test(value);
                 case 'US':
                 default:
                     return /^\d{4,5}([\-]\d{4})?$/.test(value);
             }
+        },
+
+        /**
+         * Validate United Kingdom postcode
+         * Examples:
+         * - Standard: EC1A 1BB, W1A 1HQ, M1 1AA, B33 8TH, CR2 6XH, DN55 1PT
+         * - Special cases:
+         * AI-2640, ASCN 1ZZ, GIR 0AA
+         *
+         * @see http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
+         * @param {String} value The postcode
+         * @returns {Boolean}
+         */
+        _gb: function(value) {
+            var firstChar  = '[ABCDEFGHIJKLMNOPRSTUWYZ]',     // Does not accept QVX
+                secondChar = '[ABCDEFGHKLMNOPQRSTUVWXY]',     // Does not accept IJZ
+                thirdChar  = '[ABCDEFGHJKPMNRSTUVWXY]',
+                fouthChar  = '[ABEHMNPRVWXY]',
+                fifthChar  = '[ABDEFGHJLNPQRSTUWXYZ]',
+                regexps = [
+                    // AN NAA, ANN NAA, AAN NAA, AANN NAA format
+                    new RegExp('^(' + firstChar + '{1}' + secondChar + '?[0-9]{1,2})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+                    // ANA NAA
+                    new RegExp('^(' + firstChar + '{1}[0-9]{1}' + thirdChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+                    // AANA NAA
+                    new RegExp('^(' + firstChar + '{1}' + secondChar + '{1}?[0-9]{1}' + fouthChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+
+                    new RegExp('^(BF1)(\\s*)([0-6]{1}[ABDEFGHJLNPQRST]{1}[ABDEFGHJLNPQRSTUWZYZ]{1})$', 'i'),        // BFPO postcodes
+                    /^(GIR)(\s*)(0AA)$/i,                       // Special postcode GIR 0AA
+                    /^(BFPO)(\s*)([0-9]{1,4})$/i,               // Standard BFPO numbers
+                    /^(BFPO)(\s*)(c\/o\s*[0-9]{1,3})$/i,        // c/o BFPO numbers
+                    /^([A-Z]{4})(\s*)(1ZZ)$/i,                  // Overseas Territories
+                    /^(AI-2640)$/i                              // Anguilla
+                ];
+            for (var i = 0; i < regexps.length; i++) {
+                if (regexps[i].test(value)) {
+                    return true;
+                }
+            }
+
+            return false;
         }
     };
 }(window.jQuery));