jquery-validation-rails 1.13.1 → 1.15.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +0 -1
  4. data/app/assets/javascripts/jquery.validate.additional-methods.js +1024 -908
  5. data/app/assets/javascripts/jquery.validate.js +1513 -1346
  6. data/app/assets/javascripts/jquery.validate.localization/messages_ar.js +8 -18
  7. data/app/assets/javascripts/jquery.validate.localization/messages_bg.js +8 -18
  8. data/app/assets/javascripts/jquery.validate.localization/messages_bn_BD.js +23 -0
  9. data/app/assets/javascripts/jquery.validate.localization/messages_ca.js +9 -19
  10. data/app/assets/javascripts/jquery.validate.localization/messages_cs.js +8 -18
  11. data/app/assets/javascripts/jquery.validate.localization/messages_da.js +8 -18
  12. data/app/assets/javascripts/jquery.validate.localization/messages_de.js +8 -18
  13. data/app/assets/javascripts/jquery.validate.localization/messages_el.js +8 -18
  14. data/app/assets/javascripts/jquery.validate.localization/messages_es.js +8 -18
  15. data/app/assets/javascripts/jquery.validate.localization/messages_es_AR.js +8 -18
  16. data/app/assets/javascripts/jquery.validate.localization/messages_es_PE.js +27 -0
  17. data/app/assets/javascripts/jquery.validate.localization/messages_et.js +8 -18
  18. data/app/assets/javascripts/jquery.validate.localization/messages_eu.js +8 -18
  19. data/app/assets/javascripts/jquery.validate.localization/messages_fa.js +10 -20
  20. data/app/assets/javascripts/jquery.validate.localization/messages_fi.js +12 -22
  21. data/app/assets/javascripts/jquery.validate.localization/messages_fr.js +12 -22
  22. data/app/assets/javascripts/jquery.validate.localization/messages_ge.js +23 -0
  23. data/app/assets/javascripts/jquery.validate.localization/messages_gl.js +10 -20
  24. data/app/assets/javascripts/jquery.validate.localization/messages_he.js +8 -18
  25. data/app/assets/javascripts/jquery.validate.localization/messages_hr.js +8 -18
  26. data/app/assets/javascripts/jquery.validate.localization/messages_hu.js +8 -18
  27. data/app/assets/javascripts/jquery.validate.localization/messages_hy_AM.js +23 -0
  28. data/app/assets/javascripts/jquery.validate.localization/messages_id.js +8 -18
  29. data/app/assets/javascripts/jquery.validate.localization/messages_is.js +8 -18
  30. data/app/assets/javascripts/jquery.validate.localization/messages_it.js +23 -32
  31. data/app/assets/javascripts/jquery.validate.localization/messages_ja.js +8 -18
  32. data/app/assets/javascripts/jquery.validate.localization/messages_ka.js +8 -18
  33. data/app/assets/javascripts/jquery.validate.localization/messages_kk.js +8 -18
  34. data/app/assets/javascripts/jquery.validate.localization/messages_ko.js +8 -18
  35. data/app/assets/javascripts/jquery.validate.localization/messages_lt.js +8 -18
  36. data/app/assets/javascripts/jquery.validate.localization/messages_lv.js +8 -18
  37. data/app/assets/javascripts/jquery.validate.localization/messages_mk.js +23 -0
  38. data/app/assets/javascripts/jquery.validate.localization/messages_my.js +8 -18
  39. data/app/assets/javascripts/jquery.validate.localization/messages_nl.js +9 -19
  40. data/app/assets/javascripts/jquery.validate.localization/messages_no.js +8 -18
  41. data/app/assets/javascripts/jquery.validate.localization/messages_pl.js +9 -18
  42. data/app/assets/javascripts/jquery.validate.localization/messages_pt_BR.js +58 -21
  43. data/app/assets/javascripts/jquery.validate.localization/messages_pt_PT.js +8 -18
  44. data/app/assets/javascripts/jquery.validate.localization/messages_ro.js +8 -18
  45. data/app/assets/javascripts/jquery.validate.localization/messages_ru.js +8 -18
  46. data/app/assets/javascripts/jquery.validate.localization/messages_si.js +8 -18
  47. data/app/assets/javascripts/jquery.validate.localization/messages_sk.js +10 -20
  48. data/app/assets/javascripts/jquery.validate.localization/messages_sl.js +8 -18
  49. data/app/assets/javascripts/jquery.validate.localization/messages_sr.js +8 -18
  50. data/app/assets/javascripts/jquery.validate.localization/messages_sr_lat.js +10 -20
  51. data/app/assets/javascripts/jquery.validate.localization/messages_sv.js +8 -18
  52. data/app/assets/javascripts/jquery.validate.localization/messages_th.js +8 -18
  53. data/app/assets/javascripts/jquery.validate.localization/messages_tj.js +8 -18
  54. data/app/assets/javascripts/jquery.validate.localization/messages_tr.js +9 -18
  55. data/app/assets/javascripts/jquery.validate.localization/messages_uk.js +8 -18
  56. data/app/assets/javascripts/jquery.validate.localization/messages_vi.js +8 -18
  57. data/app/assets/javascripts/jquery.validate.localization/messages_zh.js +13 -23
  58. data/app/assets/javascripts/jquery.validate.localization/messages_zh_TW.js +8 -18
  59. data/app/assets/javascripts/jquery.validate.localization/methods_de.js +6 -16
  60. data/app/assets/javascripts/jquery.validate.localization/methods_es_CL.js +6 -16
  61. data/app/assets/javascripts/jquery.validate.localization/methods_fi.js +6 -16
  62. data/app/assets/javascripts/jquery.validate.localization/methods_nl.js +4 -14
  63. data/app/assets/javascripts/jquery.validate.localization/methods_pt.js +4 -14
  64. data/jquery-validation-rails.gemspec +0 -5
  65. data/lib/jquery/validation/rails/version.rb +1 -1
  66. metadata +9 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4691809abf49bdbe7976df0d05ea7f7cbc626f20
4
- data.tar.gz: 087209bab6f17cccb3c95cf47ae1d98f883e5613
3
+ metadata.gz: 68933135192adb060190b207dab9e80b9abb6ae1
4
+ data.tar.gz: 18216f9797ca5d0d1955a860d247a6eee322795e
5
5
  SHA512:
6
- metadata.gz: fd3d64b8fe0c49136c4482107d68e3a461d0b88dfad33171c49c6c01fff65ab2cf16544b79fa2665cb3caf072f189ca57775dc5cfdd7521279b69960d0cf665c
7
- data.tar.gz: 36b29911708276c3ceec81c33cb7d48b4978248ec1fdeafcc0d80cac3e892da17da15e6e89bea68e1b50c26a451b43717816b2bd7159075f2bd93f9e0c923ea0
6
+ metadata.gz: df6a7e2036f9e3f950a1b439bc4d373cb718363e333f8b365e7a9d9d68ab83705181e27c3c113df056c655951813bd65f3f0b9191a9696c6ea9e5cf4cc24a716
7
+ data.tar.gz: 22ec87568a2a0d8d95ecab4088e29775903d431a214cf4fd9cfd730fa0556f12cdb1c4eab4d6096b5d9be8d45383cb53efe20fe050eb8545f8e81799e9adcfef
@@ -1,3 +1,7 @@
1
+ ## 1.15.0
2
+
3
+ * Update included jquery.validation files to 1.15.0
4
+
1
5
  ## 1.13.1
2
6
 
3
7
  * Update included jquery.validation files to 1.13.1
data/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # Jquery::Validation::Rails
2
2
 
3
-
4
3
  ## Installation
5
4
 
6
5
  Add this line to your application's Gemfile:
@@ -1,940 +1,1056 @@
1
1
  /*!
2
- * jQuery Validation Plugin v1.13.1
2
+ * jQuery Validation Plugin v1.15.0
3
3
  *
4
4
  * http://jqueryvalidation.org/
5
5
  *
6
- * Copyright (c) 2014 Jörn Zaefferer
6
+ * Copyright (c) 2016 Jörn Zaefferer
7
7
  * Released under the MIT license
8
8
  */
9
9
  (function( factory ) {
10
- if ( typeof define === "function" && define.amd ) {
11
- define( ["jquery", "./jquery.validate"], factory );
12
- } else {
13
- factory( jQuery );
14
- }
10
+ if ( typeof define === "function" && define.amd ) {
11
+ define( ["jquery", "./jquery.validate"], factory );
12
+ } else if (typeof module === "object" && module.exports) {
13
+ module.exports = factory( require( "jquery" ) );
14
+ } else {
15
+ factory( jQuery );
16
+ }
15
17
  }(function( $ ) {
16
18
 
17
- (function() {
19
+ ( function() {
18
20
 
19
- function stripHtml(value) {
20
- // remove html tags and space chars
21
- return value.replace(/<.[^<>]*?>/g, " ").replace(/&nbsp;|&#160;/gi, " ")
22
- // remove punctuation
23
- .replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "");
24
- }
21
+ function stripHtml( value ) {
25
22
 
26
- $.validator.addMethod("maxWords", function(value, element, params) {
27
- return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params;
28
- }, $.validator.format("Please enter {0} words or less."));
23
+ // Remove html tags and space chars
24
+ return value.replace( /<.[^<>]*?>/g, " " ).replace( /&nbsp;|&#160;/gi, " " )
29
25
 
30
- $.validator.addMethod("minWords", function(value, element, params) {
31
- return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params;
32
- }, $.validator.format("Please enter at least {0} words."));
26
+ // Remove punctuation
27
+ .replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" );
28
+ }
33
29
 
34
- $.validator.addMethod("rangeWords", function(value, element, params) {
35
- var valueStripped = stripHtml(value),
36
- regex = /\b\w+\b/g;
37
- return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];
38
- }, $.validator.format("Please enter between {0} and {1} words."));
30
+ $.validator.addMethod( "maxWords", function( value, element, params ) {
31
+ return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params;
32
+ }, $.validator.format( "Please enter {0} words or less." ) );
39
33
 
40
- }());
34
+ $.validator.addMethod( "minWords", function( value, element, params ) {
35
+ return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params;
36
+ }, $.validator.format( "Please enter at least {0} words." ) );
41
37
 
42
- // Accept a value from a file input based on a required mimetype
43
- $.validator.addMethod("accept", function(value, element, param) {
44
- // Split mime on commas in case we have multiple types we can accept
45
- var typeParam = typeof param === "string" ? param.replace(/\s/g, "").replace(/,/g, "|") : "image/*",
46
- optionalValue = this.optional(element),
47
- i, file;
48
-
49
- // Element is optional
50
- if (optionalValue) {
51
- return optionalValue;
52
- }
53
-
54
- if ($(element).attr("type") === "file") {
55
- // If we are using a wildcard, make it regex friendly
56
- typeParam = typeParam.replace(/\*/g, ".*");
57
-
58
- // Check if the element has a FileList before checking each file
59
- if (element.files && element.files.length) {
60
- for (i = 0; i < element.files.length; i++) {
61
- file = element.files[i];
62
-
63
- // Grab the mimetype from the loaded file, verify it matches
64
- if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {
65
- return false;
66
- }
67
- }
68
- }
69
- }
70
-
71
- // Either return true because we've validated each file, or because the
72
- // browser does not support element.files and the FileList feature
73
- return true;
74
- }, $.validator.format("Please enter a value with a valid mimetype."));
75
-
76
- $.validator.addMethod("alphanumeric", function(value, element) {
77
- return this.optional(element) || /^\w+$/i.test(value);
78
- }, "Letters, numbers, and underscores only please");
79
-
80
- /*
81
- * Dutch bank account numbers (not 'giro' numbers) have 9 digits
82
- * and pass the '11 check'.
83
- * We accept the notation with spaces, as that is common.
84
- * acceptable: 123456789 or 12 34 56 789
85
- */
86
- $.validator.addMethod("bankaccountNL", function(value, element) {
87
- if (this.optional(element)) {
88
- return true;
89
- }
90
- if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {
91
- return false;
92
- }
93
- // now '11 check'
94
- var account = value.replace(/ /g, ""), // remove spaces
95
- sum = 0,
96
- len = account.length,
97
- pos, factor, digit;
98
- for ( pos = 0; pos < len; pos++ ) {
99
- factor = len - pos;
100
- digit = account.substring(pos, pos + 1);
101
- sum = sum + factor * digit;
102
- }
103
- return sum % 11 === 0;
104
- }, "Please specify a valid bank account number");
105
-
106
- $.validator.addMethod("bankorgiroaccountNL", function(value, element) {
107
- return this.optional(element) ||
108
- ($.validator.methods.bankaccountNL.call(this, value, element)) ||
109
- ($.validator.methods.giroaccountNL.call(this, value, element));
110
- }, "Please specify a valid bank or giro account number");
111
-
112
- /**
113
- * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
114
- *
115
- * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
116
- *
117
- * BIC definition in detail:
118
- * - First 4 characters - bank code (only letters)
119
- * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
120
- * - Next 2 characters - location code (letters and digits)
121
- * a. shall not start with '0' or '1'
122
- * b. second character must be a letter ('O' is not allowed) or one of the following digits ('0' for test (therefore not allowed), '1' for passive participant and '2' for active participant)
123
- * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
124
- */
125
- $.validator.addMethod("bic", function(value, element) {
126
- return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value );
127
- }, "Please specify a valid BIC code");
38
+ $.validator.addMethod( "rangeWords", function( value, element, params ) {
39
+ var valueStripped = stripHtml( value ),
40
+ regex = /\b\w+\b/g;
41
+ return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ];
42
+ }, $.validator.format( "Please enter between {0} and {1} words." ) );
128
43
 
129
- /*
130
- * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
131
- * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
132
- */
133
- $.validator.addMethod( "cifES", function( value ) {
134
- "use strict";
135
-
136
- var num = [],
137
- controlDigit, sum, i, count, tmp, secondDigit;
138
-
139
- value = value.toUpperCase();
140
-
141
- // Quick format test
142
- if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
143
- return false;
144
- }
145
-
146
- for ( i = 0; i < 9; i++ ) {
147
- num[ i ] = parseInt( value.charAt( i ), 10 );
148
- }
149
-
150
- // Algorithm for checking CIF codes
151
- sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
152
- for ( count = 1; count < 8; count += 2 ) {
153
- tmp = ( 2 * num[ count ] ).toString();
154
- secondDigit = tmp.charAt( 1 );
155
-
156
- sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) );
157
- }
158
-
159
- /* The first (position 1) is a letter following the following criteria:
160
- * A. Corporations
161
- * B. LLCs
162
- * C. General partnerships
163
- * D. Companies limited partnerships
164
- * E. Communities of goods
165
- * F. Cooperative Societies
166
- * G. Associations
167
- * H. Communities of homeowners in horizontal property regime
168
- * J. Civil Societies
169
- * K. Old format
170
- * L. Old format
171
- * M. Old format
172
- * N. Nonresident entities
173
- * P. Local authorities
174
- * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
175
- * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
176
- * S. Organs of State Administration and regions
177
- * V. Agrarian Transformation
178
- * W. Permanent establishments of non-resident in Spain
179
- */
180
- if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
181
- sum += "";
182
- controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
183
- value += controlDigit;
184
- return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
185
- }
186
-
187
- return false;
188
-
189
- }, "Please specify a valid CIF number." );
190
-
191
- /* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
192
- * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
193
- * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
194
- */
195
- $.validator.addMethod("creditcardtypes", function(value, element, param) {
196
- if (/[^0-9\-]+/.test(value)) {
197
- return false;
198
- }
199
-
200
- value = value.replace(/\D/g, "");
201
-
202
- var validTypes = 0x0000;
203
-
204
- if (param.mastercard) {
205
- validTypes |= 0x0001;
206
- }
207
- if (param.visa) {
208
- validTypes |= 0x0002;
209
- }
210
- if (param.amex) {
211
- validTypes |= 0x0004;
212
- }
213
- if (param.dinersclub) {
214
- validTypes |= 0x0008;
215
- }
216
- if (param.enroute) {
217
- validTypes |= 0x0010;
218
- }
219
- if (param.discover) {
220
- validTypes |= 0x0020;
221
- }
222
- if (param.jcb) {
223
- validTypes |= 0x0040;
224
- }
225
- if (param.unknown) {
226
- validTypes |= 0x0080;
227
- }
228
- if (param.all) {
229
- validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
230
- }
231
- if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
232
- return value.length === 16;
233
- }
234
- if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
235
- return value.length === 16;
236
- }
237
- if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
238
- return value.length === 15;
239
- }
240
- if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
241
- return value.length === 14;
242
- }
243
- if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
244
- return value.length === 15;
245
- }
246
- if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
247
- return value.length === 16;
248
- }
249
- if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
250
- return value.length === 16;
251
- }
252
- if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
253
- return value.length === 15;
254
- }
255
- if (validTypes & 0x0080) { //unknown
256
- return true;
257
- }
258
- return false;
259
- }, "Please enter a valid credit card number.");
260
-
261
- /**
262
- * Validates currencies with any given symbols by @jameslouiz
263
- * Symbols can be optional or required. Symbols required by default
264
- *
265
- * Usage examples:
266
- * currency: ["£", false] - Use false for soft currency validation
267
- * currency: ["$", false]
268
- * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
269
- *
270
- * <input class="currencyInput" name="currencyInput">
271
- *
272
- * Soft symbol checking
273
- * currencyInput: {
44
+ }() );
45
+
46
+ // Accept a value from a file input based on a required mimetype
47
+ $.validator.addMethod( "accept", function( value, element, param ) {
48
+
49
+ // Split mime on commas in case we have multiple types we can accept
50
+ var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*",
51
+ optionalValue = this.optional( element ),
52
+ i, file, regex;
53
+
54
+ // Element is optional
55
+ if ( optionalValue ) {
56
+ return optionalValue;
57
+ }
58
+
59
+ if ( $( element ).attr( "type" ) === "file" ) {
60
+
61
+ // Escape string to be used in the regex
62
+ // see: http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
63
+ // Escape also "/*" as "/.*" as a wildcard
64
+ typeParam = typeParam.replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" ).replace( /,/g, "|" ).replace( "\/*", "/.*" );
65
+
66
+ // Check if the element has a FileList before checking each file
67
+ if ( element.files && element.files.length ) {
68
+ regex = new RegExp( ".?(" + typeParam + ")$", "i" );
69
+ for ( i = 0; i < element.files.length; i++ ) {
70
+ file = element.files[ i ];
71
+
72
+ // Grab the mimetype from the loaded file, verify it matches
73
+ if ( !file.type.match( regex ) ) {
74
+ return false;
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ // Either return true because we've validated each file, or because the
81
+ // browser does not support element.files and the FileList feature
82
+ return true;
83
+ }, $.validator.format( "Please enter a value with a valid mimetype." ) );
84
+
85
+ $.validator.addMethod( "alphanumeric", function( value, element ) {
86
+ return this.optional( element ) || /^\w+$/i.test( value );
87
+ }, "Letters, numbers, and underscores only please" );
88
+
89
+ /*
90
+ * Dutch bank account numbers (not 'giro' numbers) have 9 digits
91
+ * and pass the '11 check'.
92
+ * We accept the notation with spaces, as that is common.
93
+ * acceptable: 123456789 or 12 34 56 789
94
+ */
95
+ $.validator.addMethod( "bankaccountNL", function( value, element ) {
96
+ if ( this.optional( element ) ) {
97
+ return true;
98
+ }
99
+ if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) {
100
+ return false;
101
+ }
102
+
103
+ // Now '11 check'
104
+ var account = value.replace( / /g, "" ), // Remove spaces
105
+ sum = 0,
106
+ len = account.length,
107
+ pos, factor, digit;
108
+ for ( pos = 0; pos < len; pos++ ) {
109
+ factor = len - pos;
110
+ digit = account.substring( pos, pos + 1 );
111
+ sum = sum + factor * digit;
112
+ }
113
+ return sum % 11 === 0;
114
+ }, "Please specify a valid bank account number" );
115
+
116
+ $.validator.addMethod( "bankorgiroaccountNL", function( value, element ) {
117
+ return this.optional( element ) ||
118
+ ( $.validator.methods.bankaccountNL.call( this, value, element ) ) ||
119
+ ( $.validator.methods.giroaccountNL.call( this, value, element ) );
120
+ }, "Please specify a valid bank or giro account number" );
121
+
122
+ /**
123
+ * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
124
+ *
125
+ * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
126
+ *
127
+ * Validation is case-insensitive. Please make sure to normalize input yourself.
128
+ *
129
+ * BIC definition in detail:
130
+ * - First 4 characters - bank code (only letters)
131
+ * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
132
+ * - Next 2 characters - location code (letters and digits)
133
+ * a. shall not start with '0' or '1'
134
+ * b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing)
135
+ * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
136
+ */
137
+ $.validator.addMethod( "bic", function( value, element ) {
138
+ return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() );
139
+ }, "Please specify a valid BIC code" );
140
+
141
+ /*
142
+ * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
143
+ * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
144
+ */
145
+ $.validator.addMethod( "cifES", function( value ) {
146
+ "use strict";
147
+
148
+ var num = [],
149
+ controlDigit, sum, i, count, tmp, secondDigit;
150
+
151
+ value = value.toUpperCase();
152
+
153
+ // Quick format test
154
+ if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
155
+ return false;
156
+ }
157
+
158
+ for ( i = 0; i < 9; i++ ) {
159
+ num[ i ] = parseInt( value.charAt( i ), 10 );
160
+ }
161
+
162
+ // Algorithm for checking CIF codes
163
+ sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
164
+ for ( count = 1; count < 8; count += 2 ) {
165
+ tmp = ( 2 * num[ count ] ).toString();
166
+ secondDigit = tmp.charAt( 1 );
167
+
168
+ sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) );
169
+ }
170
+
171
+ /* The first (position 1) is a letter following the following criteria:
172
+ * A. Corporations
173
+ * B. LLCs
174
+ * C. General partnerships
175
+ * D. Companies limited partnerships
176
+ * E. Communities of goods
177
+ * F. Cooperative Societies
178
+ * G. Associations
179
+ * H. Communities of homeowners in horizontal property regime
180
+ * J. Civil Societies
181
+ * K. Old format
182
+ * L. Old format
183
+ * M. Old format
184
+ * N. Nonresident entities
185
+ * P. Local authorities
186
+ * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
187
+ * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
188
+ * S. Organs of State Administration and regions
189
+ * V. Agrarian Transformation
190
+ * W. Permanent establishments of non-resident in Spain
191
+ */
192
+ if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
193
+ sum += "";
194
+ controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
195
+ value += controlDigit;
196
+ return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
197
+ }
198
+
199
+ return false;
200
+
201
+ }, "Please specify a valid CIF number." );
202
+
203
+ /*
204
+ * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.
205
+ * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.
206
+ */
207
+ $.validator.addMethod( "cpfBR", function( value ) {
208
+
209
+ // Removing special characters from value
210
+ value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
211
+
212
+ // Checking value to have 11 digits only
213
+ if ( value.length !== 11 ) {
214
+ return false;
215
+ }
216
+
217
+ var sum = 0,
218
+ firstCN, secondCN, checkResult, i;
219
+
220
+ firstCN = parseInt( value.substring( 9, 10 ), 10 );
221
+ secondCN = parseInt( value.substring( 10, 11 ), 10 );
222
+
223
+ checkResult = function( sum, cn ) {
224
+ var result = ( sum * 10 ) % 11;
225
+ if ( ( result === 10 ) || ( result === 11 ) ) {
226
+ result = 0;
227
+ }
228
+ return ( result === cn );
229
+ };
230
+
231
+ // Checking for dump data
232
+ if ( value === "" ||
233
+ value === "00000000000" ||
234
+ value === "11111111111" ||
235
+ value === "22222222222" ||
236
+ value === "33333333333" ||
237
+ value === "44444444444" ||
238
+ value === "55555555555" ||
239
+ value === "66666666666" ||
240
+ value === "77777777777" ||
241
+ value === "88888888888" ||
242
+ value === "99999999999"
243
+ ) {
244
+ return false;
245
+ }
246
+
247
+ // Step 1 - using first Check Number:
248
+ for ( i = 1; i <= 9; i++ ) {
249
+ sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i );
250
+ }
251
+
252
+ // If first Check Number (CN) is valid, move to Step 2 - using second Check Number:
253
+ if ( checkResult( sum, firstCN ) ) {
254
+ sum = 0;
255
+ for ( i = 1; i <= 10; i++ ) {
256
+ sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i );
257
+ }
258
+ return checkResult( sum, secondCN );
259
+ }
260
+ return false;
261
+
262
+ }, "Please specify a valid CPF number" );
263
+
264
+ // http://jqueryvalidation.org/creditcard-method/
265
+ // based on http://en.wikipedia.org/wiki/Luhn_algorithm
266
+ $.validator.addMethod( "creditcard", function( value, element ) {
267
+ if ( this.optional( element ) ) {
268
+ return "dependency-mismatch";
269
+ }
270
+
271
+ // Accept only spaces, digits and dashes
272
+ if ( /[^0-9 \-]+/.test( value ) ) {
273
+ return false;
274
+ }
275
+
276
+ var nCheck = 0,
277
+ nDigit = 0,
278
+ bEven = false,
279
+ n, cDigit;
280
+
281
+ value = value.replace( /\D/g, "" );
282
+
283
+ // Basing min and max length on
284
+ // http://developer.ean.com/general_info/Valid_Credit_Card_Types
285
+ if ( value.length < 13 || value.length > 19 ) {
286
+ return false;
287
+ }
288
+
289
+ for ( n = value.length - 1; n >= 0; n-- ) {
290
+ cDigit = value.charAt( n );
291
+ nDigit = parseInt( cDigit, 10 );
292
+ if ( bEven ) {
293
+ if ( ( nDigit *= 2 ) > 9 ) {
294
+ nDigit -= 9;
295
+ }
296
+ }
297
+
298
+ nCheck += nDigit;
299
+ bEven = !bEven;
300
+ }
301
+
302
+ return ( nCheck % 10 ) === 0;
303
+ }, "Please enter a valid credit card number." );
304
+
305
+ /* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
306
+ * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
307
+ * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
308
+ */
309
+ $.validator.addMethod( "creditcardtypes", function( value, element, param ) {
310
+ if ( /[^0-9\-]+/.test( value ) ) {
311
+ return false;
312
+ }
313
+
314
+ value = value.replace( /\D/g, "" );
315
+
316
+ var validTypes = 0x0000;
317
+
318
+ if ( param.mastercard ) {
319
+ validTypes |= 0x0001;
320
+ }
321
+ if ( param.visa ) {
322
+ validTypes |= 0x0002;
323
+ }
324
+ if ( param.amex ) {
325
+ validTypes |= 0x0004;
326
+ }
327
+ if ( param.dinersclub ) {
328
+ validTypes |= 0x0008;
329
+ }
330
+ if ( param.enroute ) {
331
+ validTypes |= 0x0010;
332
+ }
333
+ if ( param.discover ) {
334
+ validTypes |= 0x0020;
335
+ }
336
+ if ( param.jcb ) {
337
+ validTypes |= 0x0040;
338
+ }
339
+ if ( param.unknown ) {
340
+ validTypes |= 0x0080;
341
+ }
342
+ if ( param.all ) {
343
+ validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
344
+ }
345
+ if ( validTypes & 0x0001 && /^(5[12345])/.test( value ) ) { // Mastercard
346
+ return value.length === 16;
347
+ }
348
+ if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa
349
+ return value.length === 16;
350
+ }
351
+ if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex
352
+ return value.length === 15;
353
+ }
354
+ if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub
355
+ return value.length === 14;
356
+ }
357
+ if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute
358
+ return value.length === 15;
359
+ }
360
+ if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover
361
+ return value.length === 16;
362
+ }
363
+ if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb
364
+ return value.length === 16;
365
+ }
366
+ if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb
367
+ return value.length === 15;
368
+ }
369
+ if ( validTypes & 0x0080 ) { // Unknown
370
+ return true;
371
+ }
372
+ return false;
373
+ }, "Please enter a valid credit card number." );
374
+
375
+ /**
376
+ * Validates currencies with any given symbols by @jameslouiz
377
+ * Symbols can be optional or required. Symbols required by default
378
+ *
379
+ * Usage examples:
380
+ * currency: ["£", false] - Use false for soft currency validation
381
+ * currency: ["$", false]
382
+ * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
383
+ *
384
+ * <input class="currencyInput" name="currencyInput">
385
+ *
386
+ * Soft symbol checking
387
+ * currencyInput: {
274
388
  * currency: ["$", false]
275
389
  * }
276
- *
277
- * Strict symbol checking (default)
278
- * currencyInput: {
390
+ *
391
+ * Strict symbol checking (default)
392
+ * currencyInput: {
279
393
  * currency: "$"
280
394
  * //OR
281
395
  * currency: ["$", true]
282
396
  * }
283
- *
284
- * Multiple Symbols
285
- * currencyInput: {
397
+ *
398
+ * Multiple Symbols
399
+ * currencyInput: {
286
400
  * currency: "$,£,¢"
287
401
  * }
288
- */
289
- $.validator.addMethod("currency", function(value, element, param) {
290
- var isParamString = typeof param === "string",
291
- symbol = isParamString ? param : param[0],
292
- soft = isParamString ? true : param[1],
293
- regex;
294
-
295
- symbol = symbol.replace(/,/g, "");
296
- symbol = soft ? symbol + "]" : symbol + "]?";
297
- regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
298
- regex = new RegExp(regex);
299
- return this.optional(element) || regex.test(value);
300
-
301
- }, "Please specify a valid currency");
302
-
303
- $.validator.addMethod("dateFA", function(value, element) {
304
- return this.optional(element) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(value);
305
- }, "Please enter a correct date");
306
-
307
- /**
308
- * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
309
- *
310
- * @example $.validator.methods.date("01/01/1900")
311
- * @result true
312
- *
313
- * @example $.validator.methods.date("01/13/1990")
314
- * @result false
315
- *
316
- * @example $.validator.methods.date("01.01.1900")
317
- * @result false
318
- *
319
- * @example <input name="pippo" class="{dateITA:true}" />
320
- * @desc Declares an optional input element whose value must be a valid date.
321
- *
322
- * @name $.validator.methods.dateITA
323
- * @type Boolean
324
- * @cat Plugins/Validate/Methods
325
- */
326
- $.validator.addMethod("dateITA", function(value, element) {
327
- var check = false,
328
- re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
329
- adata, gg, mm, aaaa, xdata;
330
- if ( re.test(value)) {
331
- adata = value.split("/");
332
- gg = parseInt(adata[0], 10);
333
- mm = parseInt(adata[1], 10);
334
- aaaa = parseInt(adata[2], 10);
335
- xdata = new Date(aaaa, mm - 1, gg, 12, 0, 0, 0);
336
- if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth () === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
337
- check = true;
338
- } else {
339
- check = false;
340
- }
341
- } else {
342
- check = false;
343
- }
344
- return this.optional(element) || check;
345
- }, "Please enter a correct date");
346
-
347
- $.validator.addMethod("dateNL", function(value, element) {
348
- return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);
349
- }, "Please enter a correct date");
402
+ */
403
+ $.validator.addMethod( "currency", function( value, element, param ) {
404
+ var isParamString = typeof param === "string",
405
+ symbol = isParamString ? param : param[ 0 ],
406
+ soft = isParamString ? true : param[ 1 ],
407
+ regex;
408
+
409
+ symbol = symbol.replace( /,/g, "" );
410
+ symbol = soft ? symbol + "]" : symbol + "]?";
411
+ regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
412
+ regex = new RegExp( regex );
413
+ return this.optional( element ) || regex.test( value );
414
+
415
+ }, "Please specify a valid currency" );
416
+
417
+ $.validator.addMethod( "dateFA", function( value, element ) {
418
+ return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value );
419
+ }, $.validator.messages.date );
420
+
421
+ /**
422
+ * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
423
+ *
424
+ * @example $.validator.methods.date("01/01/1900")
425
+ * @result true
426
+ *
427
+ * @example $.validator.methods.date("01/13/1990")
428
+ * @result false
429
+ *
430
+ * @example $.validator.methods.date("01.01.1900")
431
+ * @result false
432
+ *
433
+ * @example <input name="pippo" class="{dateITA:true}" />
434
+ * @desc Declares an optional input element whose value must be a valid date.
435
+ *
436
+ * @name $.validator.methods.dateITA
437
+ * @type Boolean
438
+ * @cat Plugins/Validate/Methods
439
+ */
440
+ $.validator.addMethod( "dateITA", function( value, element ) {
441
+ var check = false,
442
+ re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
443
+ adata, gg, mm, aaaa, xdata;
444
+ if ( re.test( value ) ) {
445
+ adata = value.split( "/" );
446
+ gg = parseInt( adata[ 0 ], 10 );
447
+ mm = parseInt( adata[ 1 ], 10 );
448
+ aaaa = parseInt( adata[ 2 ], 10 );
449
+ xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );
450
+ if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
451
+ check = true;
452
+ } else {
453
+ check = false;
454
+ }
455
+ } else {
456
+ check = false;
457
+ }
458
+ return this.optional( element ) || check;
459
+ }, $.validator.messages.date );
460
+
461
+ $.validator.addMethod( "dateNL", function( value, element ) {
462
+ return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value );
463
+ }, $.validator.messages.date );
350
464
 
351
465
  // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
352
- $.validator.addMethod("extension", function(value, element, param) {
353
- param = typeof param === "string" ? param.replace(/,/g, "|") : "png|jpe?g|gif";
354
- return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
355
- }, $.validator.format("Please enter a value with a valid extension."));
356
-
357
- /**
358
- * Dutch giro account numbers (not bank numbers) have max 7 digits
359
- */
360
- $.validator.addMethod("giroaccountNL", function(value, element) {
361
- return this.optional(element) || /^[0-9]{1,7}$/.test(value);
362
- }, "Please specify a valid giro account number");
363
-
364
- /**
365
- * IBAN is the international bank account number.
366
- * It has a country - specific format, that is checked here too
367
- */
368
- $.validator.addMethod("iban", function(value, element) {
369
- // some quick simple tests to prevent needless work
370
- if (this.optional(element)) {
371
- return true;
372
- }
373
-
374
- // remove spaces and to upper case
375
- var iban = value.replace(/ /g, "").toUpperCase(),
376
- ibancheckdigits = "",
377
- leadingZeroes = true,
378
- cRest = "",
379
- cOperator = "",
380
- countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
381
-
382
- if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(iban))) {
383
- return false;
384
- }
385
-
386
- // check the country code and find the country specific format
387
- countrycode = iban.substring(0, 2);
388
- bbancountrypatterns = {
389
- "AL": "\\d{8}[\\dA-Z]{16}",
390
- "AD": "\\d{8}[\\dA-Z]{12}",
391
- "AT": "\\d{16}",
392
- "AZ": "[\\dA-Z]{4}\\d{20}",
393
- "BE": "\\d{12}",
394
- "BH": "[A-Z]{4}[\\dA-Z]{14}",
395
- "BA": "\\d{16}",
396
- "BR": "\\d{23}[A-Z][\\dA-Z]",
397
- "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
398
- "CR": "\\d{17}",
399
- "HR": "\\d{17}",
400
- "CY": "\\d{8}[\\dA-Z]{16}",
401
- "CZ": "\\d{20}",
402
- "DK": "\\d{14}",
403
- "DO": "[A-Z]{4}\\d{20}",
404
- "EE": "\\d{16}",
405
- "FO": "\\d{14}",
406
- "FI": "\\d{14}",
407
- "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
408
- "GE": "[\\dA-Z]{2}\\d{16}",
409
- "DE": "\\d{18}",
410
- "GI": "[A-Z]{4}[\\dA-Z]{15}",
411
- "GR": "\\d{7}[\\dA-Z]{16}",
412
- "GL": "\\d{14}",
413
- "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
414
- "HU": "\\d{24}",
415
- "IS": "\\d{22}",
416
- "IE": "[\\dA-Z]{4}\\d{14}",
417
- "IL": "\\d{19}",
418
- "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
419
- "KZ": "\\d{3}[\\dA-Z]{13}",
420
- "KW": "[A-Z]{4}[\\dA-Z]{22}",
421
- "LV": "[A-Z]{4}[\\dA-Z]{13}",
422
- "LB": "\\d{4}[\\dA-Z]{20}",
423
- "LI": "\\d{5}[\\dA-Z]{12}",
424
- "LT": "\\d{16}",
425
- "LU": "\\d{3}[\\dA-Z]{13}",
426
- "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
427
- "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
428
- "MR": "\\d{23}",
429
- "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
430
- "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
431
- "MD": "[\\dA-Z]{2}\\d{18}",
432
- "ME": "\\d{18}",
433
- "NL": "[A-Z]{4}\\d{10}",
434
- "NO": "\\d{11}",
435
- "PK": "[\\dA-Z]{4}\\d{16}",
436
- "PS": "[\\dA-Z]{4}\\d{21}",
437
- "PL": "\\d{24}",
438
- "PT": "\\d{21}",
439
- "RO": "[A-Z]{4}[\\dA-Z]{16}",
440
- "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
441
- "SA": "\\d{2}[\\dA-Z]{18}",
442
- "RS": "\\d{18}",
443
- "SK": "\\d{20}",
444
- "SI": "\\d{15}",
445
- "ES": "\\d{20}",
446
- "SE": "\\d{20}",
447
- "CH": "\\d{5}[\\dA-Z]{12}",
448
- "TN": "\\d{20}",
449
- "TR": "\\d{5}[\\dA-Z]{17}",
450
- "AE": "\\d{3}\\d{16}",
451
- "GB": "[A-Z]{4}\\d{14}",
452
- "VG": "[\\dA-Z]{4}\\d{16}"
453
- };
454
-
455
- bbanpattern = bbancountrypatterns[countrycode];
456
- // As new countries will start using IBAN in the
457
- // future, we only check if the countrycode is known.
458
- // This prevents false negatives, while almost all
459
- // false positives introduced by this, will be caught
460
- // by the checksum validation below anyway.
461
- // Strict checking should return FALSE for unknown
462
- // countries.
463
- if (typeof bbanpattern !== "undefined") {
464
- ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");
465
- if (!(ibanregexp.test(iban))) {
466
- return false; // invalid country specific format
467
- }
468
- }
469
-
470
- // now check the checksum, first convert to digits
471
- ibancheck = iban.substring(4, iban.length) + iban.substring(0, 4);
472
- for (i = 0; i < ibancheck.length; i++) {
473
- charAt = ibancheck.charAt(i);
474
- if (charAt !== "0") {
475
- leadingZeroes = false;
476
- }
477
- if (!leadingZeroes) {
478
- ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(charAt);
479
- }
480
- }
481
-
482
- // calculate the result of: ibancheckdigits % 97
483
- for (p = 0; p < ibancheckdigits.length; p++) {
484
- cChar = ibancheckdigits.charAt(p);
485
- cOperator = "" + cRest + "" + cChar;
486
- cRest = cOperator % 97;
487
- }
488
- return cRest === 1;
489
- }, "Please specify a valid IBAN");
490
-
491
- $.validator.addMethod("integer", function(value, element) {
492
- return this.optional(element) || /^-?\d+$/.test(value);
493
- }, "A positive or negative non-decimal number please");
494
-
495
- $.validator.addMethod("ipv4", function(value, element) {
496
- return this.optional(element) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value);
497
- }, "Please enter a valid IP v4 address.");
498
-
499
- $.validator.addMethod("ipv6", function(value, element) {
500
- return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);
501
- }, "Please enter a valid IP v6 address.");
502
-
503
- $.validator.addMethod("lettersonly", function(value, element) {
504
- return this.optional(element) || /^[a-z]+$/i.test(value);
505
- }, "Letters only please");
506
-
507
- $.validator.addMethod("letterswithbasicpunc", function(value, element) {
508
- return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);
509
- }, "Letters or punctuation only please");
510
-
511
- $.validator.addMethod("mobileNL", function(value, element) {
512
- return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
513
- }, "Please specify a valid mobile number");
514
-
515
- /* For UK phone functions, do the following server side processing:
516
- * Compare original input with this RegEx pattern:
517
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
518
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
519
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
520
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
521
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
522
- */
523
- $.validator.addMethod("mobileUK", function(phone_number, element) {
524
- phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
525
- return this.optional(element) || phone_number.length > 9 &&
526
- phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/);
527
- }, "Please specify a valid mobile number");
528
-
529
- /*
530
- * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
531
- */
532
- $.validator.addMethod( "nieES", function( value ) {
533
- "use strict";
534
-
535
- value = value.toUpperCase();
536
-
537
- // Basic format test
538
- if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
539
- return false;
540
- }
541
-
542
- // Test NIE
543
- //T
544
- if ( /^[T]{1}/.test( value ) ) {
545
- return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
546
- }
547
-
548
- //XYZ
549
- if ( /^[XYZ]{1}/.test( value ) ) {
550
- return (
551
- value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
552
- value.replace( "X", "0" )
553
- .replace( "Y", "1" )
554
- .replace( "Z", "2" )
555
- .substring( 0, 8 ) % 23
556
- )
557
- );
558
- }
559
-
560
- return false;
561
-
562
- }, "Please specify a valid NIE number." );
563
-
564
- /*
565
- * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
566
- */
567
- $.validator.addMethod( "nifES", function( value ) {
568
- "use strict";
569
-
570
- value = value.toUpperCase();
571
-
572
- // Basic format test
573
- if ( !value.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)") ) {
574
- return false;
575
- }
576
-
577
- // Test NIF
578
- if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
579
- return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
580
- }
581
- // Test specials NIF (starts with K, L or M)
582
- if ( /^[KLM]{1}/.test( value ) ) {
583
- return ( value[ 8 ] === String.fromCharCode( 64 ) );
584
- }
585
-
586
- return false;
587
-
588
- }, "Please specify a valid NIF number." );
589
-
590
- $.validator.addMethod("nowhitespace", function(value, element) {
591
- return this.optional(element) || /^\S+$/i.test(value);
592
- }, "No white space please");
593
-
594
- /**
595
- * Return true if the field value matches the given format RegExp
596
- *
597
- * @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
598
- * @result true
599
- *
600
- * @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
601
- * @result false
602
- *
603
- * @name $.validator.methods.pattern
604
- * @type Boolean
605
- * @cat Plugins/Validate/Methods
606
- */
607
- $.validator.addMethod("pattern", function(value, element, param) {
608
- if (this.optional(element)) {
609
- return true;
610
- }
611
- if (typeof param === "string") {
612
- param = new RegExp("^(?:" + param + ")$");
613
- }
614
- return param.test(value);
615
- }, "Invalid format.");
616
-
617
- /**
618
- * Dutch phone numbers have 10 digits (or 11 and start with +31).
619
- */
620
- $.validator.addMethod("phoneNL", function(value, element) {
621
- return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
622
- }, "Please specify a valid phone number.");
623
-
624
- /* For UK phone functions, do the following server side processing:
625
- * Compare original input with this RegEx pattern:
626
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
627
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
628
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
629
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
630
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
631
- */
632
- $.validator.addMethod("phoneUK", function(phone_number, element) {
633
- phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
634
- return this.optional(element) || phone_number.length > 9 &&
635
- phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/);
636
- }, "Please specify a valid phone number");
637
-
638
- /**
639
- * matches US phone number format
640
- *
641
- * where the area code may not start with 1 and the prefix may not start with 1
642
- * allows '-' or ' ' as a separator and allows parens around area code
643
- * some people may want to put a '1' in front of their number
644
- *
645
- * 1(212)-999-2345 or
646
- * 212 999 2344 or
647
- * 212-999-0983
648
- *
649
- * but not
650
- * 111-123-5434
651
- * and not
652
- * 212 123 4567
653
- */
654
- $.validator.addMethod("phoneUS", function(phone_number, element) {
655
- phone_number = phone_number.replace(/\s+/g, "");
656
- return this.optional(element) || phone_number.length > 9 &&
657
- phone_number.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/);
658
- }, "Please specify a valid phone number");
659
-
660
- /* For UK phone functions, do the following server side processing:
661
- * Compare original input with this RegEx pattern:
662
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
663
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
664
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
665
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
666
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
667
- */
668
- //Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
669
- $.validator.addMethod("phonesUK", function(phone_number, element) {
670
- phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
671
- return this.optional(element) || phone_number.length > 9 &&
672
- phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/);
673
- }, "Please specify a valid uk phone number");
674
-
675
- /**
676
- * Matches a valid Canadian Postal Code
677
- *
678
- * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
679
- * @result true
680
- *
681
- * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
682
- * @result false
683
- *
684
- * @name jQuery.validator.methods.postalCodeCA
685
- * @type Boolean
686
- * @cat Plugins/Validate/Methods
687
- */
688
- $.validator.addMethod( "postalCodeCA", function( value, element ) {
689
- return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test( value );
690
- }, "Please specify a valid postal code" );
691
-
692
- /*
693
- * Valida CEPs do brasileiros:
694
- *
695
- * Formatos aceitos:
696
- * 99999-999
697
- * 99.999-999
698
- * 99999999
699
- */
700
- $.validator.addMethod("postalcodeBR", function(cep_value, element) {
701
- return this.optional(element) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
702
- }, "Informe um CEP válido.");
703
-
704
- /* Matches Italian postcode (CAP) */
705
- $.validator.addMethod("postalcodeIT", function(value, element) {
706
- return this.optional(element) || /^\d{5}$/.test(value);
707
- }, "Please specify a valid postal code");
708
-
709
- $.validator.addMethod("postalcodeNL", function(value, element) {
710
- return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
711
- }, "Please specify a valid postal code");
466
+ $.validator.addMethod( "extension", function( value, element, param ) {
467
+ param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif";
468
+ return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) );
469
+ }, $.validator.format( "Please enter a value with a valid extension." ) );
470
+
471
+ /**
472
+ * Dutch giro account numbers (not bank numbers) have max 7 digits
473
+ */
474
+ $.validator.addMethod( "giroaccountNL", function( value, element ) {
475
+ return this.optional( element ) || /^[0-9]{1,7}$/.test( value );
476
+ }, "Please specify a valid giro account number" );
477
+
478
+ /**
479
+ * IBAN is the international bank account number.
480
+ * It has a country - specific format, that is checked here too
481
+ *
482
+ * Validation is case-insensitive. Please make sure to normalize input yourself.
483
+ */
484
+ $.validator.addMethod( "iban", function( value, element ) {
485
+
486
+ // Some quick simple tests to prevent needless work
487
+ if ( this.optional( element ) ) {
488
+ return true;
489
+ }
490
+
491
+ // Remove spaces and to upper case
492
+ var iban = value.replace( / /g, "" ).toUpperCase(),
493
+ ibancheckdigits = "",
494
+ leadingZeroes = true,
495
+ cRest = "",
496
+ cOperator = "",
497
+ countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
498
+
499
+ // Check the country code and find the country specific format
500
+ countrycode = iban.substring( 0, 2 );
501
+ bbancountrypatterns = {
502
+ "AL": "\\d{8}[\\dA-Z]{16}",
503
+ "AD": "\\d{8}[\\dA-Z]{12}",
504
+ "AT": "\\d{16}",
505
+ "AZ": "[\\dA-Z]{4}\\d{20}",
506
+ "BE": "\\d{12}",
507
+ "BH": "[A-Z]{4}[\\dA-Z]{14}",
508
+ "BA": "\\d{16}",
509
+ "BR": "\\d{23}[A-Z][\\dA-Z]",
510
+ "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
511
+ "CR": "\\d{17}",
512
+ "HR": "\\d{17}",
513
+ "CY": "\\d{8}[\\dA-Z]{16}",
514
+ "CZ": "\\d{20}",
515
+ "DK": "\\d{14}",
516
+ "DO": "[A-Z]{4}\\d{20}",
517
+ "EE": "\\d{16}",
518
+ "FO": "\\d{14}",
519
+ "FI": "\\d{14}",
520
+ "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
521
+ "GE": "[\\dA-Z]{2}\\d{16}",
522
+ "DE": "\\d{18}",
523
+ "GI": "[A-Z]{4}[\\dA-Z]{15}",
524
+ "GR": "\\d{7}[\\dA-Z]{16}",
525
+ "GL": "\\d{14}",
526
+ "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
527
+ "HU": "\\d{24}",
528
+ "IS": "\\d{22}",
529
+ "IE": "[\\dA-Z]{4}\\d{14}",
530
+ "IL": "\\d{19}",
531
+ "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
532
+ "KZ": "\\d{3}[\\dA-Z]{13}",
533
+ "KW": "[A-Z]{4}[\\dA-Z]{22}",
534
+ "LV": "[A-Z]{4}[\\dA-Z]{13}",
535
+ "LB": "\\d{4}[\\dA-Z]{20}",
536
+ "LI": "\\d{5}[\\dA-Z]{12}",
537
+ "LT": "\\d{16}",
538
+ "LU": "\\d{3}[\\dA-Z]{13}",
539
+ "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
540
+ "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
541
+ "MR": "\\d{23}",
542
+ "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
543
+ "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
544
+ "MD": "[\\dA-Z]{2}\\d{18}",
545
+ "ME": "\\d{18}",
546
+ "NL": "[A-Z]{4}\\d{10}",
547
+ "NO": "\\d{11}",
548
+ "PK": "[\\dA-Z]{4}\\d{16}",
549
+ "PS": "[\\dA-Z]{4}\\d{21}",
550
+ "PL": "\\d{24}",
551
+ "PT": "\\d{21}",
552
+ "RO": "[A-Z]{4}[\\dA-Z]{16}",
553
+ "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
554
+ "SA": "\\d{2}[\\dA-Z]{18}",
555
+ "RS": "\\d{18}",
556
+ "SK": "\\d{20}",
557
+ "SI": "\\d{15}",
558
+ "ES": "\\d{20}",
559
+ "SE": "\\d{20}",
560
+ "CH": "\\d{5}[\\dA-Z]{12}",
561
+ "TN": "\\d{20}",
562
+ "TR": "\\d{5}[\\dA-Z]{17}",
563
+ "AE": "\\d{3}\\d{16}",
564
+ "GB": "[A-Z]{4}\\d{14}",
565
+ "VG": "[\\dA-Z]{4}\\d{16}"
566
+ };
567
+
568
+ bbanpattern = bbancountrypatterns[ countrycode ];
569
+
570
+ // As new countries will start using IBAN in the
571
+ // future, we only check if the countrycode is known.
572
+ // This prevents false negatives, while almost all
573
+ // false positives introduced by this, will be caught
574
+ // by the checksum validation below anyway.
575
+ // Strict checking should return FALSE for unknown
576
+ // countries.
577
+ if ( typeof bbanpattern !== "undefined" ) {
578
+ ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" );
579
+ if ( !( ibanregexp.test( iban ) ) ) {
580
+ return false; // Invalid country specific format
581
+ }
582
+ }
583
+
584
+ // Now check the checksum, first convert to digits
585
+ ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 );
586
+ for ( i = 0; i < ibancheck.length; i++ ) {
587
+ charAt = ibancheck.charAt( i );
588
+ if ( charAt !== "0" ) {
589
+ leadingZeroes = false;
590
+ }
591
+ if ( !leadingZeroes ) {
592
+ ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt );
593
+ }
594
+ }
595
+
596
+ // Calculate the result of: ibancheckdigits % 97
597
+ for ( p = 0; p < ibancheckdigits.length; p++ ) {
598
+ cChar = ibancheckdigits.charAt( p );
599
+ cOperator = "" + cRest + "" + cChar;
600
+ cRest = cOperator % 97;
601
+ }
602
+ return cRest === 1;
603
+ }, "Please specify a valid IBAN" );
604
+
605
+ $.validator.addMethod( "integer", function( value, element ) {
606
+ return this.optional( element ) || /^-?\d+$/.test( value );
607
+ }, "A positive or negative non-decimal number please" );
608
+
609
+ $.validator.addMethod( "ipv4", function( value, element ) {
610
+ return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value );
611
+ }, "Please enter a valid IP v4 address." );
612
+
613
+ $.validator.addMethod( "ipv6", function( value, element ) {
614
+ return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value );
615
+ }, "Please enter a valid IP v6 address." );
616
+
617
+ $.validator.addMethod( "lettersonly", function( value, element ) {
618
+ return this.optional( element ) || /^[a-z]+$/i.test( value );
619
+ }, "Letters only please" );
620
+
621
+ $.validator.addMethod( "letterswithbasicpunc", function( value, element ) {
622
+ return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value );
623
+ }, "Letters or punctuation only please" );
624
+
625
+ $.validator.addMethod( "mobileNL", function( value, element ) {
626
+ return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
627
+ }, "Please specify a valid mobile number" );
628
+
629
+ /* For UK phone functions, do the following server side processing:
630
+ * Compare original input with this RegEx pattern:
631
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
632
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
633
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
634
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
635
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
636
+ */
637
+ $.validator.addMethod( "mobileUK", function( phone_number, element ) {
638
+ phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
639
+ return this.optional( element ) || phone_number.length > 9 &&
640
+ phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ );
641
+ }, "Please specify a valid mobile number" );
642
+
643
+ /*
644
+ * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
645
+ */
646
+ $.validator.addMethod( "nieES", function( value ) {
647
+ "use strict";
648
+
649
+ value = value.toUpperCase();
650
+
651
+ // Basic format test
652
+ if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
653
+ return false;
654
+ }
655
+
656
+ // Test NIE
657
+ //T
658
+ if ( /^[T]{1}/.test( value ) ) {
659
+ return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
660
+ }
661
+
662
+ //XYZ
663
+ if ( /^[XYZ]{1}/.test( value ) ) {
664
+ return (
665
+ value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
666
+ value.replace( "X", "0" )
667
+ .replace( "Y", "1" )
668
+ .replace( "Z", "2" )
669
+ .substring( 0, 8 ) % 23
670
+ )
671
+ );
672
+ }
673
+
674
+ return false;
675
+
676
+ }, "Please specify a valid NIE number." );
677
+
678
+ /*
679
+ * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
680
+ */
681
+ $.validator.addMethod( "nifES", function( value ) {
682
+ "use strict";
683
+
684
+ value = value.toUpperCase();
685
+
686
+ // Basic format test
687
+ if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
688
+ return false;
689
+ }
690
+
691
+ // Test NIF
692
+ if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
693
+ return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
694
+ }
695
+
696
+ // Test specials NIF (starts with K, L or M)
697
+ if ( /^[KLM]{1}/.test( value ) ) {
698
+ return ( value[ 8 ] === String.fromCharCode( 64 ) );
699
+ }
700
+
701
+ return false;
702
+
703
+ }, "Please specify a valid NIF number." );
704
+
705
+ jQuery.validator.addMethod( "notEqualTo", function( value, element, param ) {
706
+ return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param );
707
+ }, "Please enter a different value, values must not be the same." );
708
+
709
+ $.validator.addMethod( "nowhitespace", function( value, element ) {
710
+ return this.optional( element ) || /^\S+$/i.test( value );
711
+ }, "No white space please" );
712
+
713
+ /**
714
+ * Return true if the field value matches the given format RegExp
715
+ *
716
+ * @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
717
+ * @result true
718
+ *
719
+ * @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
720
+ * @result false
721
+ *
722
+ * @name $.validator.methods.pattern
723
+ * @type Boolean
724
+ * @cat Plugins/Validate/Methods
725
+ */
726
+ $.validator.addMethod( "pattern", function( value, element, param ) {
727
+ if ( this.optional( element ) ) {
728
+ return true;
729
+ }
730
+ if ( typeof param === "string" ) {
731
+ param = new RegExp( "^(?:" + param + ")$" );
732
+ }
733
+ return param.test( value );
734
+ }, "Invalid format." );
735
+
736
+ /**
737
+ * Dutch phone numbers have 10 digits (or 11 and start with +31).
738
+ */
739
+ $.validator.addMethod( "phoneNL", function( value, element ) {
740
+ return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
741
+ }, "Please specify a valid phone number." );
742
+
743
+ /* For UK phone functions, do the following server side processing:
744
+ * Compare original input with this RegEx pattern:
745
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
746
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
747
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
748
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
749
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
750
+ */
751
+ $.validator.addMethod( "phoneUK", function( phone_number, element ) {
752
+ phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
753
+ return this.optional( element ) || phone_number.length > 9 &&
754
+ phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ );
755
+ }, "Please specify a valid phone number" );
756
+
757
+ /**
758
+ * Matches US phone number format
759
+ *
760
+ * where the area code may not start with 1 and the prefix may not start with 1
761
+ * allows '-' or ' ' as a separator and allows parens around area code
762
+ * some people may want to put a '1' in front of their number
763
+ *
764
+ * 1(212)-999-2345 or
765
+ * 212 999 2344 or
766
+ * 212-999-0983
767
+ *
768
+ * but not
769
+ * 111-123-5434
770
+ * and not
771
+ * 212 123 4567
772
+ */
773
+ $.validator.addMethod( "phoneUS", function( phone_number, element ) {
774
+ phone_number = phone_number.replace( /\s+/g, "" );
775
+ return this.optional( element ) || phone_number.length > 9 &&
776
+ phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/ );
777
+ }, "Please specify a valid phone number" );
778
+
779
+ /* For UK phone functions, do the following server side processing:
780
+ * Compare original input with this RegEx pattern:
781
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
782
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
783
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
784
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
785
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
786
+ */
787
+
788
+ // Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
789
+ $.validator.addMethod( "phonesUK", function( phone_number, element ) {
790
+ phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
791
+ return this.optional( element ) || phone_number.length > 9 &&
792
+ phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ );
793
+ }, "Please specify a valid uk phone number" );
794
+
795
+ /**
796
+ * Matches a valid Canadian Postal Code
797
+ *
798
+ * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
799
+ * @result true
800
+ *
801
+ * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
802
+ * @result false
803
+ *
804
+ * @name jQuery.validator.methods.postalCodeCA
805
+ * @type Boolean
806
+ * @cat Plugins/Validate/Methods
807
+ */
808
+ $.validator.addMethod( "postalCodeCA", function( value, element ) {
809
+ return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value );
810
+ }, "Please specify a valid postal code" );
811
+
812
+ /*
813
+ * Valida CEPs do brasileiros:
814
+ *
815
+ * Formatos aceitos:
816
+ * 99999-999
817
+ * 99.999-999
818
+ * 99999999
819
+ */
820
+ $.validator.addMethod( "postalcodeBR", function( cep_value, element ) {
821
+ return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
822
+ }, "Informe um CEP válido." );
823
+
824
+ /* Matches Italian postcode (CAP) */
825
+ $.validator.addMethod( "postalcodeIT", function( value, element ) {
826
+ return this.optional( element ) || /^\d{5}$/.test( value );
827
+ }, "Please specify a valid postal code" );
828
+
829
+ $.validator.addMethod( "postalcodeNL", function( value, element ) {
830
+ return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value );
831
+ }, "Please specify a valid postal code" );
712
832
 
713
833
  // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
714
- $.validator.addMethod("postcodeUK", function(value, element) {
715
- return this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(value);
716
- }, "Please specify a valid UK postcode");
717
-
718
- /*
719
- * Lets you say "at least X inputs that match selector Y must be filled."
720
- *
721
- * The end result is that neither of these inputs:
722
- *
723
- * <input class="productinfo" name="partnumber">
724
- * <input class="productinfo" name="description">
725
- *
726
- * ...will validate unless at least one of them is filled.
727
- *
728
- * partnumber: {require_from_group: [1,".productinfo"]},
729
- * description: {require_from_group: [1,".productinfo"]}
730
- *
731
- * options[0]: number of fields that must be filled in the group
732
- * options[1]: CSS selector that defines the group of conditionally required fields
733
- */
734
- $.validator.addMethod("require_from_group", function(value, element, options) {
735
- var $fields = $(options[1], element.form),
736
- $fieldsFirst = $fields.eq(0),
737
- validator = $fieldsFirst.data("valid_req_grp") ? $fieldsFirst.data("valid_req_grp") : $.extend({}, this),
738
- isValid = $fields.filter(function() {
739
- return validator.elementValue(this);
740
- }).length >= options[0];
741
-
742
- // Store the cloned validator for future validation
743
- $fieldsFirst.data("valid_req_grp", validator);
744
-
745
- // If element isn't being validated, run each require_from_group field's validation rules
746
- if (!$(element).data("being_validated")) {
747
- $fields.data("being_validated", true);
748
- $fields.each(function() {
749
- validator.element(this);
750
- });
751
- $fields.data("being_validated", false);
752
- }
753
- return isValid;
754
- }, $.validator.format("Please fill at least {0} of these fields."));
755
-
756
- /*
757
- * Lets you say "either at least X inputs that match selector Y must be filled,
758
- * OR they must all be skipped (left blank)."
759
- *
760
- * The end result, is that none of these inputs:
761
- *
762
- * <input class="productinfo" name="partnumber">
763
- * <input class="productinfo" name="description">
764
- * <input class="productinfo" name="color">
765
- *
766
- * ...will validate unless either at least two of them are filled,
767
- * OR none of them are.
768
- *
769
- * partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
770
- * description: {skip_or_fill_minimum: [2,".productinfo"]},
771
- * color: {skip_or_fill_minimum: [2,".productinfo"]}
772
- *
773
- * options[0]: number of fields that must be filled in the group
774
- * options[1]: CSS selector that defines the group of conditionally required fields
775
- *
776
- */
777
- $.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
778
- var $fields = $(options[1], element.form),
779
- $fieldsFirst = $fields.eq(0),
780
- validator = $fieldsFirst.data("valid_skip") ? $fieldsFirst.data("valid_skip") : $.extend({}, this),
781
- numberFilled = $fields.filter(function() {
782
- return validator.elementValue(this);
783
- }).length,
784
- isValid = numberFilled === 0 || numberFilled >= options[0];
785
-
786
- // Store the cloned validator for future validation
787
- $fieldsFirst.data("valid_skip", validator);
788
-
789
- // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
790
- if (!$(element).data("being_validated")) {
791
- $fields.data("being_validated", true);
792
- $fields.each(function() {
793
- validator.element(this);
794
- });
795
- $fields.data("being_validated", false);
796
- }
797
- return isValid;
798
- }, $.validator.format("Please either skip these fields or fill at least {0} of them."));
799
-
800
- /* Validates US States and/or Territories by @jdforsythe
801
- * Can be case insensitive or require capitalization - default is case insensitive
802
- * Can include US Territories or not - default does not
803
- * Can include US Military postal abbreviations (AA, AE, AP) - default does not
804
- *
805
- * Note: "States" always includes DC (District of Colombia)
806
- *
807
- * Usage examples:
808
- *
809
- * This is the default - case insensitive, no territories, no military zones
810
- * stateInput: {
811
- * caseSensitive: false,
812
- * includeTerritories: false,
813
- * includeMilitary: false
814
- * }
815
- *
816
- * Only allow capital letters, no territories, no military zones
817
- * stateInput: {
818
- * caseSensitive: false
819
- * }
820
- *
821
- * Case insensitive, include territories but not military zones
822
- * stateInput: {
823
- * includeTerritories: true
824
- * }
825
- *
826
- * Only allow capital letters, include territories and military zones
827
- * stateInput: {
828
- * caseSensitive: true,
829
- * includeTerritories: true,
830
- * includeMilitary: true
831
- * }
832
- *
833
- *
834
- *
835
- */
836
-
837
- jQuery.validator.addMethod("stateUS", function(value, element, options) {
838
- var isDefault = typeof options === "undefined",
839
- caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
840
- includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
841
- includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
842
- regex;
843
-
844
- if (!includeTerritories && !includeMilitary) {
845
- regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
846
- } else if (includeTerritories && includeMilitary) {
847
- regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
848
- } else if (includeTerritories) {
849
- regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
850
- } else {
851
- regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
852
- }
853
-
854
- regex = caseSensitive ? new RegExp(regex) : new RegExp(regex, "i");
855
- return this.optional(element) || regex.test(value);
856
- },
857
- "Please specify a valid state");
834
+ $.validator.addMethod( "postcodeUK", function( value, element ) {
835
+ return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value );
836
+ }, "Please specify a valid UK postcode" );
837
+
838
+ /*
839
+ * Lets you say "at least X inputs that match selector Y must be filled."
840
+ *
841
+ * The end result is that neither of these inputs:
842
+ *
843
+ * <input class="productinfo" name="partnumber">
844
+ * <input class="productinfo" name="description">
845
+ *
846
+ * ...will validate unless at least one of them is filled.
847
+ *
848
+ * partnumber: {require_from_group: [1,".productinfo"]},
849
+ * description: {require_from_group: [1,".productinfo"]}
850
+ *
851
+ * options[0]: number of fields that must be filled in the group
852
+ * options[1]: CSS selector that defines the group of conditionally required fields
853
+ */
854
+ $.validator.addMethod( "require_from_group", function( value, element, options ) {
855
+ var $fields = $( options[ 1 ], element.form ),
856
+ $fieldsFirst = $fields.eq( 0 ),
857
+ validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ),
858
+ isValid = $fields.filter( function() {
859
+ return validator.elementValue( this );
860
+ } ).length >= options[ 0 ];
861
+
862
+ // Store the cloned validator for future validation
863
+ $fieldsFirst.data( "valid_req_grp", validator );
864
+
865
+ // If element isn't being validated, run each require_from_group field's validation rules
866
+ if ( !$( element ).data( "being_validated" ) ) {
867
+ $fields.data( "being_validated", true );
868
+ $fields.each( function() {
869
+ validator.element( this );
870
+ } );
871
+ $fields.data( "being_validated", false );
872
+ }
873
+ return isValid;
874
+ }, $.validator.format( "Please fill at least {0} of these fields." ) );
875
+
876
+ /*
877
+ * Lets you say "either at least X inputs that match selector Y must be filled,
878
+ * OR they must all be skipped (left blank)."
879
+ *
880
+ * The end result, is that none of these inputs:
881
+ *
882
+ * <input class="productinfo" name="partnumber">
883
+ * <input class="productinfo" name="description">
884
+ * <input class="productinfo" name="color">
885
+ *
886
+ * ...will validate unless either at least two of them are filled,
887
+ * OR none of them are.
888
+ *
889
+ * partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
890
+ * description: {skip_or_fill_minimum: [2,".productinfo"]},
891
+ * color: {skip_or_fill_minimum: [2,".productinfo"]}
892
+ *
893
+ * options[0]: number of fields that must be filled in the group
894
+ * options[1]: CSS selector that defines the group of conditionally required fields
895
+ *
896
+ */
897
+ $.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) {
898
+ var $fields = $( options[ 1 ], element.form ),
899
+ $fieldsFirst = $fields.eq( 0 ),
900
+ validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ),
901
+ numberFilled = $fields.filter( function() {
902
+ return validator.elementValue( this );
903
+ } ).length,
904
+ isValid = numberFilled === 0 || numberFilled >= options[ 0 ];
905
+
906
+ // Store the cloned validator for future validation
907
+ $fieldsFirst.data( "valid_skip", validator );
908
+
909
+ // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
910
+ if ( !$( element ).data( "being_validated" ) ) {
911
+ $fields.data( "being_validated", true );
912
+ $fields.each( function() {
913
+ validator.element( this );
914
+ } );
915
+ $fields.data( "being_validated", false );
916
+ }
917
+ return isValid;
918
+ }, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) );
919
+
920
+ /* Validates US States and/or Territories by @jdforsythe
921
+ * Can be case insensitive or require capitalization - default is case insensitive
922
+ * Can include US Territories or not - default does not
923
+ * Can include US Military postal abbreviations (AA, AE, AP) - default does not
924
+ *
925
+ * Note: "States" always includes DC (District of Colombia)
926
+ *
927
+ * Usage examples:
928
+ *
929
+ * This is the default - case insensitive, no territories, no military zones
930
+ * stateInput: {
931
+ * caseSensitive: false,
932
+ * includeTerritories: false,
933
+ * includeMilitary: false
934
+ * }
935
+ *
936
+ * Only allow capital letters, no territories, no military zones
937
+ * stateInput: {
938
+ * caseSensitive: false
939
+ * }
940
+ *
941
+ * Case insensitive, include territories but not military zones
942
+ * stateInput: {
943
+ * includeTerritories: true
944
+ * }
945
+ *
946
+ * Only allow capital letters, include territories and military zones
947
+ * stateInput: {
948
+ * caseSensitive: true,
949
+ * includeTerritories: true,
950
+ * includeMilitary: true
951
+ * }
952
+ *
953
+ */
954
+ $.validator.addMethod( "stateUS", function( value, element, options ) {
955
+ var isDefault = typeof options === "undefined",
956
+ caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
957
+ includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
958
+ includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
959
+ regex;
960
+
961
+ if ( !includeTerritories && !includeMilitary ) {
962
+ regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
963
+ } else if ( includeTerritories && includeMilitary ) {
964
+ regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
965
+ } else if ( includeTerritories ) {
966
+ regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
967
+ } else {
968
+ regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
969
+ }
970
+
971
+ regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" );
972
+ return this.optional( element ) || regex.test( value );
973
+ }, "Please specify a valid state" );
858
974
 
859
975
  // TODO check if value starts with <, otherwise don't try stripping anything
860
- $.validator.addMethod("strippedminlength", function(value, element, param) {
861
- return $(value).text().length >= param;
862
- }, $.validator.format("Please enter at least {0} characters"));
863
-
864
- $.validator.addMethod("time", function(value, element) {
865
- return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);
866
- }, "Please enter a valid time, between 00:00 and 23:59");
867
-
868
- $.validator.addMethod("time12h", function(value, element) {
869
- return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
870
- }, "Please enter a valid time in 12-hour am/pm format");
871
-
872
- // same as url, but TLD is optional
873
- $.validator.addMethod("url2", function(value, element) {
874
- return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
875
- }, $.validator.messages.url);
876
-
877
- /**
878
- * Return true, if the value is a valid vehicle identification number (VIN).
879
- *
880
- * Works with all kind of text inputs.
881
- *
882
- * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
883
- * @desc Declares a required input element whose value must be a valid vehicle identification number.
884
- *
885
- * @name $.validator.methods.vinUS
886
- * @type Boolean
887
- * @cat Plugins/Validate/Methods
888
- */
889
- $.validator.addMethod("vinUS", function(v) {
890
- if (v.length !== 17) {
891
- return false;
892
- }
893
-
894
- var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
895
- VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
896
- FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
897
- rs = 0,
898
- i, n, d, f, cd, cdv;
899
-
900
- for (i = 0; i < 17; i++) {
901
- f = FL[i];
902
- d = v.slice(i, i + 1);
903
- if (i === 8) {
904
- cdv = d;
905
- }
906
- if (!isNaN(d)) {
907
- d *= f;
908
- } else {
909
- for (n = 0; n < LL.length; n++) {
910
- if (d.toUpperCase() === LL[n]) {
911
- d = VL[n];
912
- d *= f;
913
- if (isNaN(cdv) && n === 8) {
914
- cdv = LL[n];
915
- }
916
- break;
917
- }
918
- }
919
- }
920
- rs += d;
921
- }
922
- cd = rs % 11;
923
- if (cd === 10) {
924
- cd = "X";
925
- }
926
- if (cd === cdv) {
927
- return true;
928
- }
929
- return false;
930
- }, "The specified vehicle identification number (VIN) is invalid.");
931
-
932
- $.validator.addMethod("zipcodeUS", function(value, element) {
933
- return this.optional(element) || /^\d{5}(-\d{4})?$/.test(value);
934
- }, "The specified US ZIP Code is invalid");
935
-
936
- $.validator.addMethod("ziprange", function(value, element) {
937
- return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);
938
- }, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx");
976
+ $.validator.addMethod( "strippedminlength", function( value, element, param ) {
977
+ return $( value ).text().length >= param;
978
+ }, $.validator.format( "Please enter at least {0} characters" ) );
979
+
980
+ $.validator.addMethod( "time", function( value, element ) {
981
+ return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
982
+ }, "Please enter a valid time, between 00:00 and 23:59" );
983
+
984
+ $.validator.addMethod( "time12h", function( value, element ) {
985
+ return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value );
986
+ }, "Please enter a valid time in 12-hour am/pm format" );
987
+
988
+ // Same as url, but TLD is optional
989
+ $.validator.addMethod( "url2", function( value, element ) {
990
+ return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
991
+ }, $.validator.messages.url );
992
+
993
+ /**
994
+ * Return true, if the value is a valid vehicle identification number (VIN).
995
+ *
996
+ * Works with all kind of text inputs.
997
+ *
998
+ * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
999
+ * @desc Declares a required input element whose value must be a valid vehicle identification number.
1000
+ *
1001
+ * @name $.validator.methods.vinUS
1002
+ * @type Boolean
1003
+ * @cat Plugins/Validate/Methods
1004
+ */
1005
+ $.validator.addMethod( "vinUS", function( v ) {
1006
+ if ( v.length !== 17 ) {
1007
+ return false;
1008
+ }
1009
+
1010
+ var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
1011
+ VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
1012
+ FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
1013
+ rs = 0,
1014
+ i, n, d, f, cd, cdv;
1015
+
1016
+ for ( i = 0; i < 17; i++ ) {
1017
+ f = FL[ i ];
1018
+ d = v.slice( i, i + 1 );
1019
+ if ( i === 8 ) {
1020
+ cdv = d;
1021
+ }
1022
+ if ( !isNaN( d ) ) {
1023
+ d *= f;
1024
+ } else {
1025
+ for ( n = 0; n < LL.length; n++ ) {
1026
+ if ( d.toUpperCase() === LL[ n ] ) {
1027
+ d = VL[ n ];
1028
+ d *= f;
1029
+ if ( isNaN( cdv ) && n === 8 ) {
1030
+ cdv = LL[ n ];
1031
+ }
1032
+ break;
1033
+ }
1034
+ }
1035
+ }
1036
+ rs += d;
1037
+ }
1038
+ cd = rs % 11;
1039
+ if ( cd === 10 ) {
1040
+ cd = "X";
1041
+ }
1042
+ if ( cd === cdv ) {
1043
+ return true;
1044
+ }
1045
+ return false;
1046
+ }, "The specified vehicle identification number (VIN) is invalid." );
1047
+
1048
+ $.validator.addMethod( "zipcodeUS", function( value, element ) {
1049
+ return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value );
1050
+ }, "The specified US ZIP Code is invalid" );
1051
+
1052
+ $.validator.addMethod( "ziprange", function( value, element ) {
1053
+ return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value );
1054
+ }, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" );
939
1055
 
940
1056
  }));