jquery-validation-rails 1.11.1.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/javascripts/jquery.validate.additional-methods.js +634 -418
  4. data/app/assets/javascripts/jquery.validate.js +202 -140
  5. data/app/assets/javascripts/jquery.validate.localization/messages_ar.js +3 -3
  6. data/app/assets/javascripts/jquery.validate.localization/messages_bg.js +4 -4
  7. data/app/assets/javascripts/jquery.validate.localization/messages_ca.js +3 -3
  8. data/app/assets/javascripts/jquery.validate.localization/messages_cs.js +3 -3
  9. data/app/assets/javascripts/jquery.validate.localization/messages_da.js +2 -2
  10. data/app/assets/javascripts/jquery.validate.localization/messages_de.js +2 -2
  11. data/app/assets/javascripts/jquery.validate.localization/messages_el.js +3 -3
  12. data/app/assets/javascripts/jquery.validate.localization/messages_es.js +8 -5
  13. data/app/assets/javascripts/jquery.validate.localization/messages_es_AR.js +29 -0
  14. data/app/assets/javascripts/jquery.validate.localization/messages_et.js +2 -2
  15. data/app/assets/javascripts/jquery.validate.localization/messages_eu.js +3 -3
  16. data/app/assets/javascripts/jquery.validate.localization/messages_fa.js +3 -3
  17. data/app/assets/javascripts/jquery.validate.localization/messages_fi.js +1 -1
  18. data/app/assets/javascripts/jquery.validate.localization/messages_fr.js +8 -5
  19. data/app/assets/javascripts/jquery.validate.localization/messages_he.js +3 -3
  20. data/app/assets/javascripts/jquery.validate.localization/messages_hr.js +3 -3
  21. data/app/assets/javascripts/jquery.validate.localization/messages_hu.js +2 -2
  22. data/app/assets/javascripts/jquery.validate.localization/messages_id.js +24 -0
  23. data/app/assets/javascripts/jquery.validate.localization/messages_is.js +23 -0
  24. data/app/assets/javascripts/jquery.validate.localization/messages_it.js +7 -4
  25. data/app/assets/javascripts/jquery.validate.localization/messages_ja.js +9 -9
  26. data/app/assets/javascripts/jquery.validate.localization/messages_ka.js +3 -3
  27. data/app/assets/javascripts/jquery.validate.localization/messages_kk.js +9 -9
  28. data/app/assets/javascripts/jquery.validate.localization/messages_ko.js +13 -13
  29. data/app/assets/javascripts/jquery.validate.localization/messages_lt.js +9 -9
  30. data/app/assets/javascripts/jquery.validate.localization/messages_lv.js +3 -3
  31. data/app/assets/javascripts/jquery.validate.localization/messages_my.js +3 -3
  32. data/app/assets/javascripts/jquery.validate.localization/messages_nl.js +3 -3
  33. data/app/assets/javascripts/jquery.validate.localization/messages_no.js +2 -2
  34. data/app/assets/javascripts/jquery.validate.localization/messages_pl.js +3 -3
  35. data/app/assets/javascripts/jquery.validate.localization/messages_pt_BR.js +8 -5
  36. data/app/assets/javascripts/jquery.validate.localization/messages_pt_PT.js +6 -3
  37. data/app/assets/javascripts/jquery.validate.localization/messages_ro.js +3 -3
  38. data/app/assets/javascripts/jquery.validate.localization/messages_ru.js +3 -3
  39. data/app/assets/javascripts/jquery.validate.localization/messages_si.js +2 -2
  40. data/app/assets/javascripts/jquery.validate.localization/messages_sk.js +2 -2
  41. data/app/assets/javascripts/jquery.validate.localization/messages_sl.js +3 -3
  42. data/app/assets/javascripts/jquery.validate.localization/messages_sr.js +5 -5
  43. data/app/assets/javascripts/jquery.validate.localization/messages_sr_lat.js +25 -0
  44. data/app/assets/javascripts/jquery.validate.localization/messages_sv.js +1 -1
  45. data/app/assets/javascripts/jquery.validate.localization/messages_th.js +3 -3
  46. data/app/assets/javascripts/jquery.validate.localization/messages_tj.js +25 -0
  47. data/app/assets/javascripts/jquery.validate.localization/messages_tr.js +3 -3
  48. data/app/assets/javascripts/jquery.validate.localization/messages_uk.js +3 -3
  49. data/app/assets/javascripts/jquery.validate.localization/messages_vi.js +9 -9
  50. data/app/assets/javascripts/jquery.validate.localization/messages_zh.js +19 -19
  51. data/app/assets/javascripts/jquery.validate.localization/messages_zh_TW.js +15 -15
  52. data/app/assets/javascripts/jquery.validate.localization/methods_de.js +1 -1
  53. data/app/assets/javascripts/jquery.validate.localization/methods_es_CL.js +12 -0
  54. data/app/assets/javascripts/jquery.validate.localization/methods_nl.js +1 -1
  55. data/app/assets/javascripts/jquery.validate.localization/methods_pt.js +1 -1
  56. data/lib/jquery/validation/rails/version.rb +1 -1
  57. metadata +20 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 520e04ab8b6d08cb8f46ae6bb98c468d48e8df69
4
- data.tar.gz: 8319b15b00eb005a2caa02c4d28df9e64a2a01a6
3
+ metadata.gz: 55f9e31badb7154b56ce386a3e8644de647583ac
4
+ data.tar.gz: 70216628f38ad1d2556f0021954b1f89d778baa9
5
5
  SHA512:
6
- metadata.gz: 1c661ca28ae072be68fd40b88705034e3efbedde0284473519f278ae9497024707f2cae3772f81ffe722df07a54a661fa47c6fd882e2dedeede1c949edae1391
7
- data.tar.gz: c08d96648d65aa88ddec6e525cf50768411a41083f6afbe209a73f60aba05c673370338cda55de6404e7065a94c795fc883c4454b8402c166a4afa11ee22a0f6
6
+ metadata.gz: 9f9086a2a76137bc12e03cc50100c538b02489b4c99f93086efb5fca346a53421e2120ddd737f27edfe7ad5b125275bedaa52997cc7e3107be3b5138261ac7c7
7
+ data.tar.gz: 4cbe6f1e9b6fb205fbec648850ef1412e105433888a998714d607bc9025c5e8c64400b896d358f5e3fed61a0d077d8da51c35d42e11573d7000062b90e171dd6
@@ -1,3 +1,7 @@
1
+ ## 1.12.0
2
+
3
+ * Update included jquery.validation files to 1.12.0
4
+
1
5
  ## 1.11.1.1
2
6
 
3
7
  * Update gemspec to allow Rails >= 4.0 to use gem
@@ -1,22 +1,20 @@
1
1
  /*!
2
- * jQuery Validation Plugin 1.11.1
2
+ * jQuery Validation Plugin v1.12.0
3
3
  *
4
- * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
- * http://docs.jquery.com/Plugins/Validation
4
+ * http://jqueryvalidation.org/
6
5
  *
7
- * Copyright 2013 Jörn Zaefferer
8
- * Released under the MIT license:
9
- * http://www.opensource.org/licenses/mit-license.php
6
+ * Copyright (c) 2014 Jörn Zaefferer
7
+ * Released under the MIT license
10
8
  */
11
-
12
9
  (function() {
13
10
 
14
11
  function stripHtml(value) {
15
12
  // remove html tags and space chars
16
- return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')
13
+ return value.replace(/<.[^<>]*?>/g, " ").replace(/&nbsp;|&#160;/gi, " ")
17
14
  // remove punctuation
18
- .replace(/[.(),;:!?%#$'"_+=\/\-]*/g,'');
15
+ .replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "");
19
16
  }
17
+
20
18
  jQuery.validator.addMethod("maxWords", function(value, element, params) {
21
19
  return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params;
22
20
  }, jQuery.validator.format("Please enter {0} words or less."));
@@ -26,93 +24,273 @@
26
24
  }, jQuery.validator.format("Please enter at least {0} words."));
27
25
 
28
26
  jQuery.validator.addMethod("rangeWords", function(value, element, params) {
29
- var valueStripped = stripHtml(value);
30
- var regex = /\b\w+\b/g;
27
+ var valueStripped = stripHtml(value),
28
+ regex = /\b\w+\b/g;
31
29
  return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];
32
30
  }, jQuery.validator.format("Please enter between {0} and {1} words."));
33
31
 
34
32
  }());
35
33
 
36
- jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) {
37
- return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);
38
- }, "Letters or punctuation only please");
34
+ // Accept a value from a file input based on a required mimetype
35
+ jQuery.validator.addMethod("accept", function(value, element, param) {
36
+ // Split mime on commas in case we have multiple types we can accept
37
+ var typeParam = typeof param === "string" ? param.replace(/\s/g, "").replace(/,/g, "|") : "image/*",
38
+ optionalValue = this.optional(element),
39
+ i, file;
39
40
 
40
- jQuery.validator.addMethod("alphanumeric", function(value, element) {
41
- return this.optional(element) || /^\w+$/i.test(value);
42
- }, "Letters, numbers, and underscores only please");
41
+ // Element is optional
42
+ if (optionalValue) {
43
+ return optionalValue;
44
+ }
43
45
 
44
- jQuery.validator.addMethod("lettersonly", function(value, element) {
45
- return this.optional(element) || /^[a-z]+$/i.test(value);
46
- }, "Letters only please");
46
+ if (jQuery(element).attr("type") === "file") {
47
+ // If we are using a wildcard, make it regex friendly
48
+ typeParam = typeParam.replace(/\*/g, ".*");
47
49
 
48
- jQuery.validator.addMethod("nowhitespace", function(value, element) {
49
- return this.optional(element) || /^\S+$/i.test(value);
50
- }, "No white space please");
50
+ // Check if the element has a FileList before checking each file
51
+ if (element.files && element.files.length) {
52
+ for (i = 0; i < element.files.length; i++) {
53
+ file = element.files[i];
51
54
 
52
- jQuery.validator.addMethod("ziprange", function(value, element) {
53
- return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);
54
- }, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx");
55
+ // Grab the mimetype from the loaded file, verify it matches
56
+ if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {
57
+ return false;
58
+ }
59
+ }
60
+ }
61
+ }
55
62
 
56
- jQuery.validator.addMethod("zipcodeUS", function(value, element) {
57
- return this.optional(element) || /\d{5}-\d{4}$|^\d{5}$/.test(value);
58
- }, "The specified US ZIP Code is invalid");
63
+ // Either return true because we've validated each file, or because the
64
+ // browser does not support element.files and the FileList feature
65
+ return true;
66
+ }, jQuery.validator.format("Please enter a value with a valid mimetype."));
59
67
 
60
- jQuery.validator.addMethod("integer", function(value, element) {
61
- return this.optional(element) || /^-?\d+$/.test(value);
62
- }, "A positive or negative non-decimal number please");
68
+ jQuery.validator.addMethod("alphanumeric", function(value, element) {
69
+ return this.optional(element) || /^\w+$/i.test(value);
70
+ }, "Letters, numbers, and underscores only please");
71
+
72
+ /*
73
+ * Dutch bank account numbers (not 'giro' numbers) have 9 digits
74
+ * and pass the '11 check'.
75
+ * We accept the notation with spaces, as that is common.
76
+ * acceptable: 123456789 or 12 34 56 789
77
+ */
78
+ jQuery.validator.addMethod("bankaccountNL", function(value, element) {
79
+ if (this.optional(element)) {
80
+ return true;
81
+ }
82
+ if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {
83
+ return false;
84
+ }
85
+ // now '11 check'
86
+ var account = value.replace(/ /g, ""), // remove spaces
87
+ sum = 0,
88
+ len = account.length,
89
+ pos, factor, digit;
90
+ for ( pos = 0; pos < len; pos++ ) {
91
+ factor = len - pos;
92
+ digit = account.substring(pos, pos + 1);
93
+ sum = sum + factor * digit;
94
+ }
95
+ return sum % 11 === 0;
96
+ }, "Please specify a valid bank account number");
97
+
98
+ jQuery.validator.addMethod("bankorgiroaccountNL", function(value, element) {
99
+ return this.optional(element) ||
100
+ ($.validator.methods.bankaccountNL.call(this, value, element)) ||
101
+ ($.validator.methods.giroaccountNL.call(this, value, element));
102
+ }, "Please specify a valid bank or giro account number");
63
103
 
64
104
  /**
65
- * Return true, if the value is a valid vehicle identification number (VIN).
66
- *
67
- * Works with all kind of text inputs.
105
+ * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
68
106
  *
69
- * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
70
- * @desc Declares a required input element whose value must be a valid vehicle identification number.
107
+ * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
71
108
  *
72
- * @name jQuery.validator.methods.vinUS
73
- * @type Boolean
74
- * @cat Plugins/Validate/Methods
109
+ * BIC definition in detail:
110
+ * - First 4 characters - bank code (only letters)
111
+ * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
112
+ * - Next 2 characters - location code (letters and digits)
113
+ * a. shall not start with '0' or '1'
114
+ * 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)
115
+ * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
75
116
  */
76
- jQuery.validator.addMethod("vinUS", function(v) {
77
- if (v.length !== 17) {
117
+ jQuery.validator.addMethod("bic", function(value, element) {
118
+ 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 );
119
+ }, "Please specify a valid BIC code");
120
+
121
+ /*
122
+ * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
123
+ * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
124
+ */
125
+ jQuery.validator.addMethod( "cifES", function( value ) {
126
+ "use strict";
127
+
128
+ var num = [],
129
+ controlDigit, sum, i, count, tmp, secondDigit;
130
+
131
+ value = value.toUpperCase();
132
+
133
+ // Quick format test
134
+ 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}$)" ) ) {
78
135
  return false;
79
136
  }
80
- var i, n, d, f, cd, cdv;
81
- 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"];
82
- var VL = [1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9];
83
- var FL = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2];
84
- var rs = 0;
85
- for(i = 0; i < 17; i++){
86
- f = FL[i];
87
- d = v.slice(i,i+1);
88
- if (i === 8) {
89
- cdv = d;
90
- }
91
- if (!isNaN(d)) {
92
- d *= f;
93
- } else {
94
- for (n = 0; n < LL.length; n++) {
95
- if (d.toUpperCase() === LL[n]) {
96
- d = VL[n];
97
- d *= f;
98
- if (isNaN(cdv) && n === 8) {
99
- cdv = LL[n];
100
- }
101
- break;
102
- }
103
- }
104
- }
105
- rs += d;
137
+
138
+ for ( i = 0; i < 9; i++ ) {
139
+ num[ i ] = parseInt( value.charAt( i ), 10 );
140
+ }
141
+
142
+ // Algorithm for checking CIF codes
143
+ sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
144
+ for ( count = 1; count < 8; count += 2 ) {
145
+ tmp = ( 2 * num[ count ] ).toString();
146
+ secondDigit = tmp.charAt( 1 );
147
+
148
+ sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) );
149
+ }
150
+
151
+ /* The first (position 1) is a letter following the following criteria:
152
+ * A. Corporations
153
+ * B. LLCs
154
+ * C. General partnerships
155
+ * D. Companies limited partnerships
156
+ * E. Communities of goods
157
+ * F. Cooperative Societies
158
+ * G. Associations
159
+ * H. Communities of homeowners in horizontal property regime
160
+ * J. Civil Societies
161
+ * K. Old format
162
+ * L. Old format
163
+ * M. Old format
164
+ * N. Nonresident entities
165
+ * P. Local authorities
166
+ * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
167
+ * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
168
+ * S. Organs of State Administration and regions
169
+ * V. Agrarian Transformation
170
+ * W. Permanent establishments of non-resident in Spain
171
+ */
172
+ if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
173
+ sum += "";
174
+ controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
175
+ value += controlDigit;
176
+ return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
106
177
  }
107
- cd = rs % 11;
108
- if (cd === 10) {
109
- cd = "X";
178
+
179
+ return false;
180
+
181
+ }, "Please specify a valid CIF number." );
182
+
183
+ /* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
184
+ * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
185
+ * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
186
+ */
187
+ jQuery.validator.addMethod("creditcardtypes", function(value, element, param) {
188
+ if (/[^0-9\-]+/.test(value)) {
189
+ return false;
110
190
  }
111
- if (cd === cdv) {
191
+
192
+ value = value.replace(/\D/g, "");
193
+
194
+ var validTypes = 0x0000;
195
+
196
+ if (param.mastercard) {
197
+ validTypes |= 0x0001;
198
+ }
199
+ if (param.visa) {
200
+ validTypes |= 0x0002;
201
+ }
202
+ if (param.amex) {
203
+ validTypes |= 0x0004;
204
+ }
205
+ if (param.dinersclub) {
206
+ validTypes |= 0x0008;
207
+ }
208
+ if (param.enroute) {
209
+ validTypes |= 0x0010;
210
+ }
211
+ if (param.discover) {
212
+ validTypes |= 0x0020;
213
+ }
214
+ if (param.jcb) {
215
+ validTypes |= 0x0040;
216
+ }
217
+ if (param.unknown) {
218
+ validTypes |= 0x0080;
219
+ }
220
+ if (param.all) {
221
+ validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
222
+ }
223
+ if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
224
+ return value.length === 16;
225
+ }
226
+ if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
227
+ return value.length === 16;
228
+ }
229
+ if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
230
+ return value.length === 15;
231
+ }
232
+ if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
233
+ return value.length === 14;
234
+ }
235
+ if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
236
+ return value.length === 15;
237
+ }
238
+ if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
239
+ return value.length === 16;
240
+ }
241
+ if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
242
+ return value.length === 16;
243
+ }
244
+ if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
245
+ return value.length === 15;
246
+ }
247
+ if (validTypes & 0x0080) { //unknown
112
248
  return true;
113
249
  }
114
250
  return false;
115
- }, "The specified vehicle identification number (VIN) is invalid.");
251
+ }, "Please enter a valid credit card number.");
252
+
253
+ /**
254
+ * Validates currencies with any given symbols by @jameslouiz
255
+ * Symbols can be optional or required. Symbols required by default
256
+ *
257
+ * Usage examples:
258
+ * currency: ["£", false] - Use false for soft currency validation
259
+ * currency: ["$", false]
260
+ * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
261
+ *
262
+ * <input class="currencyInput" name="currencyInput">
263
+ *
264
+ * Soft symbol checking
265
+ * currencyInput: {
266
+ * currency: ["$", false]
267
+ * }
268
+ *
269
+ * Strict symbol checking (default)
270
+ * currencyInput: {
271
+ * currency: "$"
272
+ * //OR
273
+ * currency: ["$", true]
274
+ * }
275
+ *
276
+ * Multiple Symbols
277
+ * currencyInput: {
278
+ * currency: "$,£,¢"
279
+ * }
280
+ */
281
+ jQuery.validator.addMethod("currency", function(value, element, param) {
282
+ var isParamString = typeof param === "string",
283
+ symbol = isParamString ? param : param[0],
284
+ soft = isParamString ? true : param[1],
285
+ regex;
286
+
287
+ symbol = symbol.replace(/,/g, "");
288
+ symbol = soft ? symbol + "]" : symbol + "]?";
289
+ 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})?)$";
290
+ regex = new RegExp(regex);
291
+ return this.optional(element) || regex.test(value);
292
+
293
+ }, "Please specify a valid currency");
116
294
 
117
295
  /**
118
296
  * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
@@ -134,14 +312,15 @@ jQuery.validator.addMethod("vinUS", function(v) {
134
312
  * @cat Plugins/Validate/Methods
135
313
  */
136
314
  jQuery.validator.addMethod("dateITA", function(value, element) {
137
- var check = false;
138
- var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
139
- if( re.test(value)) {
140
- var adata = value.split('/');
141
- var gg = parseInt(adata[0],10);
142
- var mm = parseInt(adata[1],10);
143
- var aaaa = parseInt(adata[2],10);
144
- var xdata = new Date(aaaa,mm-1,gg);
315
+ var check = false,
316
+ re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
317
+ adata, gg, mm, aaaa, xdata;
318
+ if ( re.test(value)) {
319
+ adata = value.split("/");
320
+ gg = parseInt(adata[0],10);
321
+ mm = parseInt(adata[1],10);
322
+ aaaa = parseInt(adata[2],10);
323
+ xdata = new Date(aaaa, mm - 1, gg, 12, 0, 0, 0);
145
324
  if ( ( xdata.getFullYear() === aaaa ) && ( xdata.getMonth() === mm - 1 ) && ( xdata.getDate() === gg ) ){
146
325
  check = true;
147
326
  } else {
@@ -153,6 +332,23 @@ jQuery.validator.addMethod("dateITA", function(value, element) {
153
332
  return this.optional(element) || check;
154
333
  }, "Please enter a correct date");
155
334
 
335
+ jQuery.validator.addMethod("dateNL", function(value, element) {
336
+ return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);
337
+ }, "Please enter a correct date");
338
+
339
+ // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
340
+ jQuery.validator.addMethod("extension", function(value, element, param) {
341
+ param = typeof param === "string" ? param.replace(/,/g, "|") : "png|jpe?g|gif";
342
+ return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
343
+ }, jQuery.validator.format("Please enter a value with a valid extension."));
344
+
345
+ /**
346
+ * Dutch giro account numbers (not bank numbers) have max 7 digits
347
+ */
348
+ jQuery.validator.addMethod("giroaccountNL", function(value, element) {
349
+ return this.optional(element) || /^[0-9]{1,7}$/.test(value);
350
+ }, "Please specify a valid giro account number");
351
+
156
352
  /**
157
353
  * IBAN is the international bank account number.
158
354
  * It has a country - specific format, that is checked here too
@@ -162,80 +358,89 @@ jQuery.validator.addMethod("iban", function(value, element) {
162
358
  if (this.optional(element)) {
163
359
  return true;
164
360
  }
165
- if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(value))) {
361
+
362
+ // remove spaces and to upper case
363
+ var iban = value.replace(/ /g,"").toUpperCase(),
364
+ ibancheckdigits = "",
365
+ leadingZeroes = true,
366
+ cRest = "",
367
+ cOperator = "",
368
+ countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
369
+
370
+ if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(iban))) {
166
371
  return false;
167
372
  }
168
373
 
169
374
  // check the country code and find the country specific format
170
- var iban = value.replace(/ /g,'').toUpperCase(); // remove spaces and to upper case
171
- var countrycode = iban.substring(0,2);
172
- var bbancountrypatterns = {
173
- 'AL': "\\d{8}[\\dA-Z]{16}",
174
- 'AD': "\\d{8}[\\dA-Z]{12}",
175
- 'AT': "\\d{16}",
176
- 'AZ': "[\\dA-Z]{4}\\d{20}",
177
- 'BE': "\\d{12}",
178
- 'BH': "[A-Z]{4}[\\dA-Z]{14}",
179
- 'BA': "\\d{16}",
180
- 'BR': "\\d{23}[A-Z][\\dA-Z]",
181
- 'BG': "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
182
- 'CR': "\\d{17}",
183
- 'HR': "\\d{17}",
184
- 'CY': "\\d{8}[\\dA-Z]{16}",
185
- 'CZ': "\\d{20}",
186
- 'DK': "\\d{14}",
187
- 'DO': "[A-Z]{4}\\d{20}",
188
- 'EE': "\\d{16}",
189
- 'FO': "\\d{14}",
190
- 'FI': "\\d{14}",
191
- 'FR': "\\d{10}[\\dA-Z]{11}\\d{2}",
192
- 'GE': "[\\dA-Z]{2}\\d{16}",
193
- 'DE': "\\d{18}",
194
- 'GI': "[A-Z]{4}[\\dA-Z]{15}",
195
- 'GR': "\\d{7}[\\dA-Z]{16}",
196
- 'GL': "\\d{14}",
197
- 'GT': "[\\dA-Z]{4}[\\dA-Z]{20}",
198
- 'HU': "\\d{24}",
199
- 'IS': "\\d{22}",
200
- 'IE': "[\\dA-Z]{4}\\d{14}",
201
- 'IL': "\\d{19}",
202
- 'IT': "[A-Z]\\d{10}[\\dA-Z]{12}",
203
- 'KZ': "\\d{3}[\\dA-Z]{13}",
204
- 'KW': "[A-Z]{4}[\\dA-Z]{22}",
205
- 'LV': "[A-Z]{4}[\\dA-Z]{13}",
206
- 'LB': "\\d{4}[\\dA-Z]{20}",
207
- 'LI': "\\d{5}[\\dA-Z]{12}",
208
- 'LT': "\\d{16}",
209
- 'LU': "\\d{3}[\\dA-Z]{13}",
210
- 'MK': "\\d{3}[\\dA-Z]{10}\\d{2}",
211
- 'MT': "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
212
- 'MR': "\\d{23}",
213
- 'MU': "[A-Z]{4}\\d{19}[A-Z]{3}",
214
- 'MC': "\\d{10}[\\dA-Z]{11}\\d{2}",
215
- 'MD': "[\\dA-Z]{2}\\d{18}",
216
- 'ME': "\\d{18}",
217
- 'NL': "[A-Z]{4}\\d{10}",
218
- 'NO': "\\d{11}",
219
- 'PK': "[\\dA-Z]{4}\\d{16}",
220
- 'PS': "[\\dA-Z]{4}\\d{21}",
221
- 'PL': "\\d{24}",
222
- 'PT': "\\d{21}",
223
- 'RO': "[A-Z]{4}[\\dA-Z]{16}",
224
- 'SM': "[A-Z]\\d{10}[\\dA-Z]{12}",
225
- 'SA': "\\d{2}[\\dA-Z]{18}",
226
- 'RS': "\\d{18}",
227
- 'SK': "\\d{20}",
228
- 'SI': "\\d{15}",
229
- 'ES': "\\d{20}",
230
- 'SE': "\\d{20}",
231
- 'CH': "\\d{5}[\\dA-Z]{12}",
232
- 'TN': "\\d{20}",
233
- 'TR': "\\d{5}[\\dA-Z]{17}",
234
- 'AE': "\\d{3}\\d{16}",
235
- 'GB': "[A-Z]{4}\\d{14}",
236
- 'VG': "[\\dA-Z]{4}\\d{16}"
375
+ countrycode = iban.substring(0,2);
376
+ bbancountrypatterns = {
377
+ "AL": "\\d{8}[\\dA-Z]{16}",
378
+ "AD": "\\d{8}[\\dA-Z]{12}",
379
+ "AT": "\\d{16}",
380
+ "AZ": "[\\dA-Z]{4}\\d{20}",
381
+ "BE": "\\d{12}",
382
+ "BH": "[A-Z]{4}[\\dA-Z]{14}",
383
+ "BA": "\\d{16}",
384
+ "BR": "\\d{23}[A-Z][\\dA-Z]",
385
+ "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
386
+ "CR": "\\d{17}",
387
+ "HR": "\\d{17}",
388
+ "CY": "\\d{8}[\\dA-Z]{16}",
389
+ "CZ": "\\d{20}",
390
+ "DK": "\\d{14}",
391
+ "DO": "[A-Z]{4}\\d{20}",
392
+ "EE": "\\d{16}",
393
+ "FO": "\\d{14}",
394
+ "FI": "\\d{14}",
395
+ "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
396
+ "GE": "[\\dA-Z]{2}\\d{16}",
397
+ "DE": "\\d{18}",
398
+ "GI": "[A-Z]{4}[\\dA-Z]{15}",
399
+ "GR": "\\d{7}[\\dA-Z]{16}",
400
+ "GL": "\\d{14}",
401
+ "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
402
+ "HU": "\\d{24}",
403
+ "IS": "\\d{22}",
404
+ "IE": "[\\dA-Z]{4}\\d{14}",
405
+ "IL": "\\d{19}",
406
+ "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
407
+ "KZ": "\\d{3}[\\dA-Z]{13}",
408
+ "KW": "[A-Z]{4}[\\dA-Z]{22}",
409
+ "LV": "[A-Z]{4}[\\dA-Z]{13}",
410
+ "LB": "\\d{4}[\\dA-Z]{20}",
411
+ "LI": "\\d{5}[\\dA-Z]{12}",
412
+ "LT": "\\d{16}",
413
+ "LU": "\\d{3}[\\dA-Z]{13}",
414
+ "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
415
+ "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
416
+ "MR": "\\d{23}",
417
+ "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
418
+ "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
419
+ "MD": "[\\dA-Z]{2}\\d{18}",
420
+ "ME": "\\d{18}",
421
+ "NL": "[A-Z]{4}\\d{10}",
422
+ "NO": "\\d{11}",
423
+ "PK": "[\\dA-Z]{4}\\d{16}",
424
+ "PS": "[\\dA-Z]{4}\\d{21}",
425
+ "PL": "\\d{24}",
426
+ "PT": "\\d{21}",
427
+ "RO": "[A-Z]{4}[\\dA-Z]{16}",
428
+ "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
429
+ "SA": "\\d{2}[\\dA-Z]{18}",
430
+ "RS": "\\d{18}",
431
+ "SK": "\\d{20}",
432
+ "SI": "\\d{15}",
433
+ "ES": "\\d{20}",
434
+ "SE": "\\d{20}",
435
+ "CH": "\\d{5}[\\dA-Z]{12}",
436
+ "TN": "\\d{20}",
437
+ "TR": "\\d{5}[\\dA-Z]{17}",
438
+ "AE": "\\d{3}\\d{16}",
439
+ "GB": "[A-Z]{4}\\d{14}",
440
+ "VG": "[\\dA-Z]{4}\\d{16}"
237
441
  };
238
- var bbanpattern = bbancountrypatterns[countrycode];
442
+
443
+ bbanpattern = bbancountrypatterns[countrycode];
239
444
  // As new countries will start using IBAN in the
240
445
  // future, we only check if the countrycode is known.
241
446
  // This prevents false negatives, while almost all
@@ -243,19 +448,16 @@ jQuery.validator.addMethod("iban", function(value, element) {
243
448
  // by the checksum validation below anyway.
244
449
  // Strict checking should return FALSE for unknown
245
450
  // countries.
246
- if (typeof bbanpattern !== 'undefined') {
247
- var ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");
451
+ if (typeof bbanpattern !== "undefined") {
452
+ ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");
248
453
  if (!(ibanregexp.test(iban))) {
249
454
  return false; // invalid country specific format
250
455
  }
251
456
  }
252
457
 
253
458
  // now check the checksum, first convert to digits
254
- var ibancheck = iban.substring(4,iban.length) + iban.substring(0,4);
255
- var ibancheckdigits = "";
256
- var leadingZeroes = true;
257
- var charAt;
258
- for (var i =0; i<ibancheck.length; i++) {
459
+ ibancheck = iban.substring(4,iban.length) + iban.substring(0,4);
460
+ for (i = 0; i < ibancheck.length; i++) {
259
461
  charAt = ibancheck.charAt(i);
260
462
  if (charAt !== "0") {
261
463
  leadingZeroes = false;
@@ -266,225 +468,116 @@ jQuery.validator.addMethod("iban", function(value, element) {
266
468
  }
267
469
 
268
470
  // calculate the result of: ibancheckdigits % 97
269
- var cRest = '';
270
- var cOperator = '';
271
- for (var p=0; p<ibancheckdigits.length; p++) {
272
- var cChar = ibancheckdigits.charAt(p);
273
- cOperator = '' + cRest + '' + cChar;
471
+ for (p = 0; p < ibancheckdigits.length; p++) {
472
+ cChar = ibancheckdigits.charAt(p);
473
+ cOperator = "" + cRest + "" + cChar;
274
474
  cRest = cOperator % 97;
275
- }
475
+ }
276
476
  return cRest === 1;
277
477
  }, "Please specify a valid IBAN");
278
478
 
279
- jQuery.validator.addMethod("dateNL", function(value, element) {
280
- return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);
281
- }, "Please enter a correct date");
479
+ jQuery.validator.addMethod("integer", function(value, element) {
480
+ return this.optional(element) || /^-?\d+$/.test(value);
481
+ }, "A positive or negative non-decimal number please");
282
482
 
283
- /**
284
- * Dutch phone numbers have 10 digits (or 11 and start with +31).
285
- */
286
- jQuery.validator.addMethod("phoneNL", function(value, element) {
287
- 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);
288
- }, "Please specify a valid phone number.");
483
+ jQuery.validator.addMethod("ipv4", function(value, element) {
484
+ 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);
485
+ }, "Please enter a valid IP v4 address.");
486
+
487
+ jQuery.validator.addMethod("ipv6", function(value, element) {
488
+ 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);
489
+ }, "Please enter a valid IP v6 address.");
490
+
491
+ jQuery.validator.addMethod("lettersonly", function(value, element) {
492
+ return this.optional(element) || /^[a-z]+$/i.test(value);
493
+ }, "Letters only please");
494
+
495
+ jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) {
496
+ return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);
497
+ }, "Letters or punctuation only please");
289
498
 
290
499
  jQuery.validator.addMethod("mobileNL", function(value, element) {
291
500
  return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
292
501
  }, "Please specify a valid mobile number");
293
502
 
294
- jQuery.validator.addMethod("postalcodeNL", function(value, element) {
295
- return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
296
- }, "Please specify a valid postal code");
503
+ /* For UK phone functions, do the following server side processing:
504
+ * Compare original input with this RegEx pattern:
505
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
506
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
507
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
508
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
509
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
510
+ */
511
+ jQuery.validator.addMethod("mobileUK", function(phone_number, element) {
512
+ phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
513
+ return this.optional(element) || phone_number.length > 9 &&
514
+ phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/);
515
+ }, "Please specify a valid mobile number");
297
516
 
298
517
  /*
299
- * Dutch bank account numbers (not 'giro' numbers) have 9 digits
300
- * and pass the '11 check'.
301
- * We accept the notation with spaces, as that is common.
302
- * acceptable: 123456789 or 12 34 56 789
518
+ * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
303
519
  */
304
- jQuery.validator.addMethod("bankaccountNL", function(value, element) {
305
- if (this.optional(element)) {
306
- return true;
307
- }
308
- if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {
520
+ jQuery.validator.addMethod( "nieES", function( value ) {
521
+ "use strict";
522
+
523
+ value = value.toUpperCase();
524
+
525
+ // Basic format test
526
+ 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}$)" ) ) {
309
527
  return false;
310
528
  }
311
- // now '11 check'
312
- var account = value.replace(/ /g,''); // remove spaces
313
- var sum = 0;
314
- var len = account.length;
315
- for (var pos=0; pos<len; pos++) {
316
- var factor = len - pos;
317
- var digit = account.substring(pos, pos+1);
318
- sum = sum + factor * digit;
319
- }
320
- return sum % 11 === 0;
321
- }, "Please specify a valid bank account number");
322
529
 
323
- /**
324
- * Dutch giro account numbers (not bank numbers) have max 7 digits
325
- */
326
- jQuery.validator.addMethod("giroaccountNL", function(value, element) {
327
- return this.optional(element) || /^[0-9]{1,7}$/.test(value);
328
- }, "Please specify a valid giro account number");
530
+ // Test NIE
531
+ //T
532
+ if ( /^[T]{1}/.test( value ) ) {
533
+ return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
534
+ }
329
535
 
330
- jQuery.validator.addMethod("bankorgiroaccountNL", function(value, element) {
331
- return this.optional(element) ||
332
- ($.validator.methods["bankaccountNL"].call(this, value, element)) ||
333
- ($.validator.methods["giroaccountNL"].call(this, value, element));
334
- }, "Please specify a valid bank or giro account number");
536
+ //XYZ
537
+ if ( /^[XYZ]{1}/.test( value ) ) {
538
+ return (
539
+ value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
540
+ value.replace( "X", "0" )
541
+ .replace( "Y", "1" )
542
+ .replace( "Z", "2" )
543
+ .substring( 0, 8 ) % 23
544
+ )
545
+ );
546
+ }
335
547
 
548
+ return false;
336
549
 
337
- jQuery.validator.addMethod("time", function(value, element) {
338
- return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);
339
- }, "Please enter a valid time, between 00:00 and 23:59");
340
- jQuery.validator.addMethod("time12h", function(value, element) {
341
- return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
342
- }, "Please enter a valid time in 12-hour am/pm format");
550
+ }, "Please specify a valid NIE number." );
343
551
 
344
- /**
345
- * matches US phone number format
346
- *
347
- * where the area code may not start with 1 and the prefix may not start with 1
348
- * allows '-' or ' ' as a separator and allows parens around area code
349
- * some people may want to put a '1' in front of their number
350
- *
351
- * 1(212)-999-2345 or
352
- * 212 999 2344 or
353
- * 212-999-0983
354
- *
355
- * but not
356
- * 111-123-5434
357
- * and not
358
- * 212 123 4567
552
+ /*
553
+ * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
359
554
  */
360
- jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
361
- phone_number = phone_number.replace(/\s+/g, "");
362
- return this.optional(element) || phone_number.length > 9 &&
363
- phone_number.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
364
- }, "Please specify a valid phone number");
365
-
366
- jQuery.validator.addMethod('phoneUK', function(phone_number, element) {
367
- phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');
368
- return this.optional(element) || phone_number.length > 9 &&
369
- 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})$/);
370
- }, 'Please specify a valid phone number');
371
-
372
- jQuery.validator.addMethod('mobileUK', function(phone_number, element) {
373
- phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');
374
- return this.optional(element) || phone_number.length > 9 &&
375
- phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/);
376
- }, 'Please specify a valid mobile number');
377
-
378
- //Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
379
- jQuery.validator.addMethod('phonesUK', function(phone_number, element) {
380
- phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');
381
- return this.optional(element) || phone_number.length > 9 &&
382
- phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/);
383
- }, 'Please specify a valid uk phone number');
384
- // On the above three UK functions, do the following server side processing:
385
- // Compare original input with this RegEx pattern:
386
- // ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
387
- // Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
388
- // Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
389
- // A number of very detailed GB telephone number RegEx patterns can also be found at:
390
- // http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
391
-
392
- // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
393
- jQuery.validator.addMethod('postcodeUK', function(value, element) {
394
- 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);
395
- }, 'Please specify a valid UK postcode');
396
-
397
- // TODO check if value starts with <, otherwise don't try stripping anything
398
- jQuery.validator.addMethod("strippedminlength", function(value, element, param) {
399
- return jQuery(value).text().length >= param;
400
- }, jQuery.validator.format("Please enter at least {0} characters"));
555
+ jQuery.validator.addMethod( "nifES", function( value ) {
556
+ "use strict";
401
557
 
402
- // same as email, but TLD is optional
403
- jQuery.validator.addMethod("email2", function(value, element, param) {
404
- return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([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])))\.?$/i.test(value);
405
- }, jQuery.validator.messages.email);
406
-
407
- // same as url, but TLD is optional
408
- jQuery.validator.addMethod("url2", function(value, element, param) {
409
- 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);
410
- }, jQuery.validator.messages.url);
558
+ value = value.toUpperCase();
411
559
 
412
- // NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
413
- // Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
414
- // Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
415
- jQuery.validator.addMethod("creditcardtypes", function(value, element, param) {
416
- if (/[^0-9\-]+/.test(value)) {
560
+ // Basic format test
561
+ 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}$)") ) {
417
562
  return false;
418
563
  }
419
564
 
420
- value = value.replace(/\D/g, "");
421
-
422
- var validTypes = 0x0000;
423
-
424
- if (param.mastercard) {
425
- validTypes |= 0x0001;
426
- }
427
- if (param.visa) {
428
- validTypes |= 0x0002;
429
- }
430
- if (param.amex) {
431
- validTypes |= 0x0004;
432
- }
433
- if (param.dinersclub) {
434
- validTypes |= 0x0008;
435
- }
436
- if (param.enroute) {
437
- validTypes |= 0x0010;
438
- }
439
- if (param.discover) {
440
- validTypes |= 0x0020;
441
- }
442
- if (param.jcb) {
443
- validTypes |= 0x0040;
444
- }
445
- if (param.unknown) {
446
- validTypes |= 0x0080;
447
- }
448
- if (param.all) {
449
- validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
450
- }
451
- if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
452
- return value.length === 16;
453
- }
454
- if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
455
- return value.length === 16;
565
+ // Test NIF
566
+ if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
567
+ return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
456
568
  }
457
- if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
458
- return value.length === 15;
459
- }
460
- if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
461
- return value.length === 14;
462
- }
463
- if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
464
- return value.length === 15;
465
- }
466
- if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
467
- return value.length === 16;
468
- }
469
- if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
470
- return value.length === 16;
471
- }
472
- if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
473
- return value.length === 15;
474
- }
475
- if (validTypes & 0x0080) { //unknown
476
- return true;
569
+ // Test specials NIF (starts with K, L or M)
570
+ if ( /^[KLM]{1}/.test( value ) ) {
571
+ return ( value[ 8 ] === String.fromCharCode( 64 ) );
477
572
  }
573
+
478
574
  return false;
479
- }, "Please enter a valid credit card number.");
480
575
 
481
- jQuery.validator.addMethod("ipv4", function(value, element, param) {
482
- 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);
483
- }, "Please enter a valid IP v4 address.");
576
+ }, "Please specify a valid NIF number." );
484
577
 
485
- jQuery.validator.addMethod("ipv6", function(value, element, param) {
486
- 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);
487
- }, "Please enter a valid IP v6 address.");
578
+ jQuery.validator.addMethod("nowhitespace", function(value, element) {
579
+ return this.optional(element) || /^\S+$/i.test(value);
580
+ }, "No white space please");
488
581
 
489
582
  /**
490
583
  * Return true if the field value matches the given format RegExp
@@ -503,42 +596,116 @@ jQuery.validator.addMethod("pattern", function(value, element, param) {
503
596
  if (this.optional(element)) {
504
597
  return true;
505
598
  }
506
- if (typeof param === 'string') {
507
- param = new RegExp('^(?:' + param + ')$');
599
+ if (typeof param === "string") {
600
+ param = new RegExp(param);
508
601
  }
509
602
  return param.test(value);
510
603
  }, "Invalid format.");
511
604
 
605
+ /**
606
+ * Dutch phone numbers have 10 digits (or 11 and start with +31).
607
+ */
608
+ jQuery.validator.addMethod("phoneNL", function(value, element) {
609
+ 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);
610
+ }, "Please specify a valid phone number.");
611
+
612
+ /* For UK phone functions, do the following server side processing:
613
+ * Compare original input with this RegEx pattern:
614
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
615
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
616
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
617
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
618
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
619
+ */
620
+ jQuery.validator.addMethod("phoneUK", function(phone_number, element) {
621
+ phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
622
+ return this.optional(element) || phone_number.length > 9 &&
623
+ 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})$/);
624
+ }, "Please specify a valid phone number");
625
+
626
+ /**
627
+ * matches US phone number format
628
+ *
629
+ * where the area code may not start with 1 and the prefix may not start with 1
630
+ * allows '-' or ' ' as a separator and allows parens around area code
631
+ * some people may want to put a '1' in front of their number
632
+ *
633
+ * 1(212)-999-2345 or
634
+ * 212 999 2344 or
635
+ * 212-999-0983
636
+ *
637
+ * but not
638
+ * 111-123-5434
639
+ * and not
640
+ * 212 123 4567
641
+ */
642
+ jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
643
+ phone_number = phone_number.replace(/\s+/g, "");
644
+ return this.optional(element) || phone_number.length > 9 &&
645
+ 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}$/);
646
+ }, "Please specify a valid phone number");
647
+
648
+ /* For UK phone functions, do the following server side processing:
649
+ * Compare original input with this RegEx pattern:
650
+ * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
651
+ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
652
+ * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
653
+ * A number of very detailed GB telephone number RegEx patterns can also be found at:
654
+ * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
655
+ */
656
+ //Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
657
+ jQuery.validator.addMethod("phonesUK", function(phone_number, element) {
658
+ phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
659
+ return this.optional(element) || phone_number.length > 9 &&
660
+ phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/);
661
+ }, "Please specify a valid uk phone number");
662
+
663
+ jQuery.validator.addMethod("postalcodeNL", function(value, element) {
664
+ return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
665
+ }, "Please specify a valid postal code");
666
+
667
+ // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
668
+ jQuery.validator.addMethod("postcodeUK", function(value, element) {
669
+ 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);
670
+ }, "Please specify a valid UK postcode");
512
671
 
513
672
  /*
514
673
  * Lets you say "at least X inputs that match selector Y must be filled."
515
674
  *
516
675
  * The end result is that neither of these inputs:
517
676
  *
518
- * <input class="productinfo" name="partnumber">
519
- * <input class="productinfo" name="description">
677
+ * <input class="productinfo" name="partnumber">
678
+ * <input class="productinfo" name="description">
520
679
  *
521
- * ...will validate unless at least one of them is filled.
680
+ * ...will validate unless at least one of them is filled.
522
681
  *
523
- * partnumber: {require_from_group: [1,".productinfo"]},
682
+ * partnumber: {require_from_group: [1,".productinfo"]},
524
683
  * description: {require_from_group: [1,".productinfo"]}
525
684
  *
685
+ * options[0]: number of fields that must be filled in the group
686
+ * options[1]: CSS selector that defines the group of conditionally required fields
526
687
  */
527
688
  jQuery.validator.addMethod("require_from_group", function(value, element, options) {
528
- var validator = this;
529
- var selector = options[1];
530
- var validOrNot = $(selector, element.form).filter(function() {
531
- return validator.elementValue(this);
532
- }).length >= options[0];
533
-
534
- if(!$(element).data('being_validated')) {
535
- var fields = $(selector, element.form);
536
- fields.data('being_validated', true);
537
- fields.valid();
538
- fields.data('being_validated', false);
539
- }
540
- return validOrNot;
541
- }, jQuery.format("Please fill at least {0} of these fields."));
689
+ var $fields = $(options[1], element.form),
690
+ $fieldsFirst = $fields.eq(0),
691
+ validator = $fieldsFirst.data("valid_req_grp") ? $fieldsFirst.data("valid_req_grp") : $.extend({}, this),
692
+ isValid = $fields.filter(function() {
693
+ return validator.elementValue(this);
694
+ }).length >= options[0];
695
+
696
+ // Store the cloned validator for future validation
697
+ $fieldsFirst.data("valid_req_grp", validator);
698
+
699
+ // If element isn't being validated, run each require_from_group field's validation rules
700
+ if (!$(element).data("being_validated")) {
701
+ $fields.data("being_validated", true);
702
+ $fields.each(function() {
703
+ validator.element(this);
704
+ });
705
+ $fields.data("being_validated", false);
706
+ }
707
+ return isValid;
708
+ }, jQuery.validator.format("Please fill at least {0} of these fields."));
542
709
 
543
710
  /*
544
711
  * Lets you say "either at least X inputs that match selector Y must be filled,
@@ -546,72 +713,121 @@ jQuery.validator.addMethod("require_from_group", function(value, element, option
546
713
  *
547
714
  * The end result, is that none of these inputs:
548
715
  *
549
- * <input class="productinfo" name="partnumber">
550
- * <input class="productinfo" name="description">
551
- * <input class="productinfo" name="color">
716
+ * <input class="productinfo" name="partnumber">
717
+ * <input class="productinfo" name="description">
718
+ * <input class="productinfo" name="color">
552
719
  *
553
- * ...will validate unless either at least two of them are filled,
554
- * OR none of them are.
720
+ * ...will validate unless either at least two of them are filled,
721
+ * OR none of them are.
555
722
  *
556
- * partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
557
- * description: {skip_or_fill_minimum: [2,".productinfo"]},
558
- * color: {skip_or_fill_minimum: [2,".productinfo"]}
723
+ * partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
724
+ * description: {skip_or_fill_minimum: [2,".productinfo"]},
725
+ * color: {skip_or_fill_minimum: [2,".productinfo"]}
726
+ *
727
+ * options[0]: number of fields that must be filled in the group
728
+ * options[1]: CSS selector that defines the group of conditionally required fields
559
729
  *
560
730
  */
561
731
  jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
562
- var validator = this,
563
- numberRequired = options[0],
564
- selector = options[1];
565
- var numberFilled = $(selector, element.form).filter(function() {
566
- return validator.elementValue(this);
567
- }).length;
568
- var valid = numberFilled >= numberRequired || numberFilled === 0;
569
-
570
- if(!$(element).data('being_validated')) {
571
- var fields = $(selector, element.form);
572
- fields.data('being_validated', true);
573
- fields.valid();
574
- fields.data('being_validated', false);
575
- }
576
- return valid;
577
- }, jQuery.format("Please either skip these fields or fill at least {0} of them."));
732
+ var $fields = $(options[1], element.form),
733
+ $fieldsFirst = $fields.eq(0),
734
+ validator = $fieldsFirst.data("valid_skip") ? $fieldsFirst.data("valid_skip") : $.extend({}, this),
735
+ numberFilled = $fields.filter(function() {
736
+ return validator.elementValue(this);
737
+ }).length,
738
+ isValid = numberFilled === 0 || numberFilled >= options[0];
739
+
740
+ // Store the cloned validator for future validation
741
+ $fieldsFirst.data("valid_skip", validator);
742
+
743
+ // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
744
+ if (!$(element).data("being_validated")) {
745
+ $fields.data("being_validated", true);
746
+ $fields.each(function() {
747
+ validator.element(this);
748
+ });
749
+ $fields.data("being_validated", false);
750
+ }
751
+ return isValid;
752
+ }, jQuery.validator.format("Please either skip these fields or fill at least {0} of them."));
578
753
 
579
- // Accept a value from a file input based on a required mimetype
580
- jQuery.validator.addMethod("accept", function(value, element, param) {
581
- // Split mime on commas in case we have multiple types we can accept
582
- var typeParam = typeof param === "string" ? param.replace(/\s/g, '').replace(/,/g, '|') : "image/*",
583
- optionalValue = this.optional(element),
584
- i, file;
754
+ // TODO check if value starts with <, otherwise don't try stripping anything
755
+ jQuery.validator.addMethod("strippedminlength", function(value, element, param) {
756
+ return jQuery(value).text().length >= param;
757
+ }, jQuery.validator.format("Please enter at least {0} characters"));
585
758
 
586
- // Element is optional
587
- if (optionalValue) {
588
- return optionalValue;
589
- }
759
+ jQuery.validator.addMethod("time", function(value, element) {
760
+ return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);
761
+ }, "Please enter a valid time, between 00:00 and 23:59");
590
762
 
591
- if ($(element).attr("type") === "file") {
592
- // If we are using a wildcard, make it regex friendly
593
- typeParam = typeParam.replace(/\*/g, ".*");
763
+ jQuery.validator.addMethod("time12h", function(value, element) {
764
+ return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
765
+ }, "Please enter a valid time in 12-hour am/pm format");
594
766
 
595
- // Check if the element has a FileList before checking each file
596
- if (element.files && element.files.length) {
597
- for (i = 0; i < element.files.length; i++) {
598
- file = element.files[i];
767
+ // same as url, but TLD is optional
768
+ jQuery.validator.addMethod("url2", function(value, element) {
769
+ 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);
770
+ }, jQuery.validator.messages.url);
599
771
 
600
- // Grab the mimetype from the loaded file, verify it matches
601
- if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {
602
- return false;
772
+ /**
773
+ * Return true, if the value is a valid vehicle identification number (VIN).
774
+ *
775
+ * Works with all kind of text inputs.
776
+ *
777
+ * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
778
+ * @desc Declares a required input element whose value must be a valid vehicle identification number.
779
+ *
780
+ * @name jQuery.validator.methods.vinUS
781
+ * @type Boolean
782
+ * @cat Plugins/Validate/Methods
783
+ */
784
+ jQuery.validator.addMethod("vinUS", function(v) {
785
+ if (v.length !== 17) {
786
+ return false;
787
+ }
788
+
789
+ 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" ],
790
+ VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
791
+ FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
792
+ rs = 0,
793
+ i, n, d, f, cd, cdv;
794
+
795
+ for (i = 0; i < 17; i++){
796
+ f = FL[i];
797
+ d = v.slice(i,i + 1);
798
+ if (i === 8) {
799
+ cdv = d;
800
+ }
801
+ if (!isNaN(d)) {
802
+ d *= f;
803
+ } else {
804
+ for (n = 0; n < LL.length; n++) {
805
+ if (d.toUpperCase() === LL[n]) {
806
+ d = VL[n];
807
+ d *= f;
808
+ if (isNaN(cdv) && n === 8) {
809
+ cdv = LL[n];
810
+ }
811
+ break;
603
812
  }
604
813
  }
605
814
  }
815
+ rs += d;
816
+ }
817
+ cd = rs % 11;
818
+ if (cd === 10) {
819
+ cd = "X";
606
820
  }
821
+ if (cd === cdv) {
822
+ return true;
823
+ }
824
+ return false;
825
+ }, "The specified vehicle identification number (VIN) is invalid.");
607
826
 
608
- // Either return true because we've validated each file, or because the
609
- // browser does not support element.files and the FileList feature
610
- return true;
611
- }, jQuery.format("Please enter a value with a valid mimetype."));
827
+ jQuery.validator.addMethod("zipcodeUS", function(value, element) {
828
+ return this.optional(element) || /^\d{5}-\d{4}$|^\d{5}$/.test(value);
829
+ }, "The specified US ZIP Code is invalid");
612
830
 
613
- // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
614
- jQuery.validator.addMethod("extension", function(value, element, param) {
615
- param = typeof param === "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
616
- return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
617
- }, jQuery.format("Please enter a value with a valid extension."));
831
+ jQuery.validator.addMethod("ziprange", function(value, element) {
832
+ return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);
833
+ }, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx");