CLIENT GUI Framework
[vnfsdk/refrepo.git] / portal-common / src / main / webapp / common / thirdparty / jquery-validation / dist / additional-methods.js
1 /*!\r
2  * jQuery Validation Plugin 1.11.1\r
3  *\r
4  * http://bassistance.de/jquery-plugins/jquery-plugin-validation/\r
5  * http://docs.jquery.com/Plugins/Validation\r
6  *\r
7  * Copyright 2013 Jörn Zaefferer\r
8  * Released under the MIT license:\r
9  *   http://www.opensource.org/licenses/mit-license.php\r
10  */\r
11 \r
12 (function() {\r
13 \r
14         function stripHtml(value) {\r
15                 // remove html tags and space chars\r
16                 return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')\r
17                 // remove punctuation\r
18                 .replace(/[.(),;:!?%#$'"_+=\/\-]*/g,'');\r
19         }\r
20         jQuery.validator.addMethod("maxWords", function(value, element, params) {\r
21                 return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params;\r
22         }, jQuery.validator.format("Please enter {0} words or less."));\r
23 \r
24         jQuery.validator.addMethod("minWords", function(value, element, params) {\r
25                 return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params;\r
26         }, jQuery.validator.format("Please enter at least {0} words."));\r
27 \r
28         jQuery.validator.addMethod("rangeWords", function(value, element, params) {\r
29                 var valueStripped = stripHtml(value);\r
30                 var regex = /\b\w+\b/g;\r
31                 return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];\r
32         }, jQuery.validator.format("Please enter between {0} and {1} words."));\r
33 \r
34 }());\r
35 \r
36 jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) {\r
37         return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);\r
38 }, "Letters or punctuation only please");\r
39 \r
40 jQuery.validator.addMethod("alphanumeric", function(value, element) {\r
41         return this.optional(element) || /^\w+$/i.test(value);\r
42 }, "Letters, numbers, and underscores only please");\r
43 \r
44 jQuery.validator.addMethod("lettersonly", function(value, element) {\r
45         return this.optional(element) || /^[a-z]+$/i.test(value);\r
46 }, "Letters only please");\r
47 \r
48 jQuery.validator.addMethod("nowhitespace", function(value, element) {\r
49         return this.optional(element) || /^\S+$/i.test(value);\r
50 }, "No white space please");\r
51 \r
52 jQuery.validator.addMethod("ziprange", function(value, element) {\r
53         return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);\r
54 }, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx");\r
55 \r
56 jQuery.validator.addMethod("zipcodeUS", function(value, element) {\r
57         return this.optional(element) || /\d{5}-\d{4}$|^\d{5}$/.test(value);\r
58 }, "The specified US ZIP Code is invalid");\r
59 \r
60 jQuery.validator.addMethod("integer", function(value, element) {\r
61         return this.optional(element) || /^-?\d+$/.test(value);\r
62 }, "A positive or negative non-decimal number please");\r
63 \r
64 /**\r
65  * Return true, if the value is a valid vehicle identification number (VIN).\r
66  *\r
67  * Works with all kind of text inputs.\r
68  *\r
69  * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />\r
70  * @desc Declares a required input element whose value must be a valid vehicle identification number.\r
71  *\r
72  * @name jQuery.validator.methods.vinUS\r
73  * @type Boolean\r
74  * @cat Plugins/Validate/Methods\r
75  */\r
76 jQuery.validator.addMethod("vinUS", function(v) {\r
77         if (v.length !== 17) {\r
78                 return false;\r
79         }\r
80         var i, n, d, f, cd, cdv;\r
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"];\r
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];\r
83         var FL = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2];\r
84         var rs = 0;\r
85         for(i = 0; i < 17; i++){\r
86                 f = FL[i];\r
87                 d = v.slice(i,i+1);\r
88                 if (i === 8) {\r
89                         cdv = d;\r
90                 }\r
91                 if (!isNaN(d)) {\r
92                         d *= f;\r
93                 } else {\r
94                         for (n = 0; n < LL.length; n++) {\r
95                                 if (d.toUpperCase() === LL[n]) {\r
96                                         d = VL[n];\r
97                                         d *= f;\r
98                                         if (isNaN(cdv) && n === 8) {\r
99                                                 cdv = LL[n];\r
100                                         }\r
101                                         break;\r
102                                 }\r
103                         }\r
104                 }\r
105                 rs += d;\r
106         }\r
107         cd = rs % 11;\r
108         if (cd === 10) {\r
109                 cd = "X";\r
110         }\r
111         if (cd === cdv) {\r
112                 return true;\r
113         }\r
114         return false;\r
115 }, "The specified vehicle identification number (VIN) is invalid.");\r
116 \r
117 /**\r
118  * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.\r
119  *\r
120  * @example jQuery.validator.methods.date("01/01/1900")\r
121  * @result true\r
122  *\r
123  * @example jQuery.validator.methods.date("01/13/1990")\r
124  * @result false\r
125  *\r
126  * @example jQuery.validator.methods.date("01.01.1900")\r
127  * @result false\r
128  *\r
129  * @example <input name="pippo" class="{dateITA:true}" />\r
130  * @desc Declares an optional input element whose value must be a valid date.\r
131  *\r
132  * @name jQuery.validator.methods.dateITA\r
133  * @type Boolean\r
134  * @cat Plugins/Validate/Methods\r
135  */\r
136 jQuery.validator.addMethod("dateITA", function(value, element) {\r
137         var check = false;\r
138         var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;\r
139         if( re.test(value)) {\r
140                 var adata = value.split('/');\r
141                 var gg = parseInt(adata[0],10);\r
142                 var mm = parseInt(adata[1],10);\r
143                 var aaaa = parseInt(adata[2],10);\r
144                 var xdata = new Date(aaaa,mm-1,gg);\r
145                 if ( ( xdata.getFullYear() === aaaa ) && ( xdata.getMonth() === mm - 1 ) && ( xdata.getDate() === gg ) ){\r
146                         check = true;\r
147                 } else {\r
148                         check = false;\r
149                 }\r
150         } else {\r
151                 check = false;\r
152         }\r
153         return this.optional(element) || check;\r
154 }, "Please enter a correct date");\r
155 \r
156 /**\r
157  * IBAN is the international bank account number.\r
158  * It has a country - specific format, that is checked here too\r
159  */\r
160 jQuery.validator.addMethod("iban", function(value, element) {\r
161         // some quick simple tests to prevent needless work\r
162         if (this.optional(element)) {\r
163                 return true;\r
164         }\r
165         if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(value))) {\r
166                 return false;\r
167         }\r
168 \r
169         // check the country code and find the country specific format\r
170         var iban = value.replace(/ /g,'').toUpperCase(); // remove spaces and to upper case\r
171         var countrycode = iban.substring(0,2);\r
172         var bbancountrypatterns = {\r
173                 'AL': "\\d{8}[\\dA-Z]{16}",\r
174                 'AD': "\\d{8}[\\dA-Z]{12}",\r
175                 'AT': "\\d{16}",\r
176                 'AZ': "[\\dA-Z]{4}\\d{20}",\r
177                 'BE': "\\d{12}",\r
178                 'BH': "[A-Z]{4}[\\dA-Z]{14}",\r
179                 'BA': "\\d{16}",\r
180                 'BR': "\\d{23}[A-Z][\\dA-Z]",\r
181                 'BG': "[A-Z]{4}\\d{6}[\\dA-Z]{8}",\r
182                 'CR': "\\d{17}",\r
183                 'HR': "\\d{17}",\r
184                 'CY': "\\d{8}[\\dA-Z]{16}",\r
185                 'CZ': "\\d{20}",\r
186                 'DK': "\\d{14}",\r
187                 'DO': "[A-Z]{4}\\d{20}",\r
188                 'EE': "\\d{16}",\r
189                 'FO': "\\d{14}",\r
190                 'FI': "\\d{14}",\r
191                 'FR': "\\d{10}[\\dA-Z]{11}\\d{2}",\r
192                 'GE': "[\\dA-Z]{2}\\d{16}",\r
193                 'DE': "\\d{18}",\r
194                 'GI': "[A-Z]{4}[\\dA-Z]{15}",\r
195                 'GR': "\\d{7}[\\dA-Z]{16}",\r
196                 'GL': "\\d{14}",\r
197                 'GT': "[\\dA-Z]{4}[\\dA-Z]{20}",\r
198                 'HU': "\\d{24}",\r
199                 'IS': "\\d{22}",\r
200                 'IE': "[\\dA-Z]{4}\\d{14}",\r
201                 'IL': "\\d{19}",\r
202                 'IT': "[A-Z]\\d{10}[\\dA-Z]{12}",\r
203                 'KZ': "\\d{3}[\\dA-Z]{13}",\r
204                 'KW': "[A-Z]{4}[\\dA-Z]{22}",\r
205                 'LV': "[A-Z]{4}[\\dA-Z]{13}",\r
206                 'LB': "\\d{4}[\\dA-Z]{20}",\r
207                 'LI': "\\d{5}[\\dA-Z]{12}",\r
208                 'LT': "\\d{16}",\r
209                 'LU': "\\d{3}[\\dA-Z]{13}",\r
210                 'MK': "\\d{3}[\\dA-Z]{10}\\d{2}",\r
211                 'MT': "[A-Z]{4}\\d{5}[\\dA-Z]{18}",\r
212                 'MR': "\\d{23}",\r
213                 'MU': "[A-Z]{4}\\d{19}[A-Z]{3}",\r
214                 'MC': "\\d{10}[\\dA-Z]{11}\\d{2}",\r
215                 'MD': "[\\dA-Z]{2}\\d{18}",\r
216                 'ME': "\\d{18}",\r
217                 'NL': "[A-Z]{4}\\d{10}",\r
218                 'NO': "\\d{11}",\r
219                 'PK': "[\\dA-Z]{4}\\d{16}",\r
220                 'PS': "[\\dA-Z]{4}\\d{21}",\r
221                 'PL': "\\d{24}",\r
222                 'PT': "\\d{21}",\r
223                 'RO': "[A-Z]{4}[\\dA-Z]{16}",\r
224                 'SM': "[A-Z]\\d{10}[\\dA-Z]{12}",\r
225                 'SA': "\\d{2}[\\dA-Z]{18}",\r
226                 'RS': "\\d{18}",\r
227                 'SK': "\\d{20}",\r
228                 'SI': "\\d{15}",\r
229                 'ES': "\\d{20}",\r
230                 'SE': "\\d{20}",\r
231                 'CH': "\\d{5}[\\dA-Z]{12}",\r
232                 'TN': "\\d{20}",\r
233                 'TR': "\\d{5}[\\dA-Z]{17}",\r
234                 'AE': "\\d{3}\\d{16}",\r
235                 'GB': "[A-Z]{4}\\d{14}",\r
236                 'VG': "[\\dA-Z]{4}\\d{16}"\r
237         };\r
238         var bbanpattern = bbancountrypatterns[countrycode];\r
239         // As new countries will start using IBAN in the\r
240         // future, we only check if the countrycode is known.\r
241         // This prevents false negatives, while almost all\r
242         // false positives introduced by this, will be caught\r
243         // by the checksum validation below anyway.\r
244         // Strict checking should return FALSE for unknown\r
245         // countries.\r
246         if (typeof bbanpattern !== 'undefined') {\r
247                 var ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");\r
248                 if (!(ibanregexp.test(iban))) {\r
249                         return false; // invalid country specific format\r
250                 }\r
251         }\r
252 \r
253         // now check the checksum, first convert to digits\r
254         var ibancheck = iban.substring(4,iban.length) + iban.substring(0,4);\r
255         var ibancheckdigits = "";\r
256         var leadingZeroes = true;\r
257         var charAt;\r
258         for (var i =0; i<ibancheck.length; i++) {\r
259                 charAt = ibancheck.charAt(i);\r
260                 if (charAt !== "0") {\r
261                         leadingZeroes = false;\r
262                 }\r
263                 if (!leadingZeroes) {\r
264                         ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(charAt);\r
265                 }\r
266         }\r
267 \r
268         // calculate the result of: ibancheckdigits % 97\r
269     var cRest = '';\r
270     var cOperator = '';\r
271         for (var p=0; p<ibancheckdigits.length; p++) {\r
272                 var cChar = ibancheckdigits.charAt(p);\r
273                 cOperator = '' + cRest + '' + cChar;\r
274                 cRest = cOperator % 97;\r
275     }\r
276         return cRest === 1;\r
277 }, "Please specify a valid IBAN");\r
278 \r
279 jQuery.validator.addMethod("dateNL", function(value, element) {\r
280         return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);\r
281 }, "Please enter a correct date");\r
282 \r
283 /**\r
284  * Dutch phone numbers have 10 digits (or 11 and start with +31).\r
285  */\r
286 jQuery.validator.addMethod("phoneNL", function(value, element) {\r
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);\r
288 }, "Please specify a valid phone number.");\r
289 \r
290 jQuery.validator.addMethod("mobileNL", function(value, element) {\r
291         return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(value);\r
292 }, "Please specify a valid mobile number");\r
293 \r
294 jQuery.validator.addMethod("postalcodeNL", function(value, element) {\r
295         return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);\r
296 }, "Please specify a valid postal code");\r
297 \r
298 /*\r
299  * Dutch bank account numbers (not 'giro' numbers) have 9 digits\r
300  * and pass the '11 check'.\r
301  * We accept the notation with spaces, as that is common.\r
302  * acceptable: 123456789 or 12 34 56 789\r
303  */\r
304 jQuery.validator.addMethod("bankaccountNL", function(value, element) {\r
305         if (this.optional(element)) {\r
306                 return true;\r
307         }\r
308         if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {\r
309                 return false;\r
310         }\r
311         // now '11 check'\r
312         var account = value.replace(/ /g,''); // remove spaces\r
313         var sum = 0;\r
314         var len = account.length;\r
315         for (var pos=0; pos<len; pos++) {\r
316                 var factor = len - pos;\r
317                 var digit = account.substring(pos, pos+1);\r
318                 sum = sum + factor * digit;\r
319         }\r
320         return sum % 11 === 0;\r
321 }, "Please specify a valid bank account number");\r
322 \r
323 /**\r
324  * Dutch giro account numbers (not bank numbers) have max 7 digits\r
325  */\r
326 jQuery.validator.addMethod("giroaccountNL", function(value, element) {\r
327         return this.optional(element) || /^[0-9]{1,7}$/.test(value);\r
328 }, "Please specify a valid giro account number");\r
329 \r
330 jQuery.validator.addMethod("bankorgiroaccountNL", function(value, element) {\r
331         return this.optional(element) ||\r
332                         ($.validator.methods["bankaccountNL"].call(this, value, element)) ||\r
333                         ($.validator.methods["giroaccountNL"].call(this, value, element));\r
334 }, "Please specify a valid bank or giro account number");\r
335 \r
336 \r
337 jQuery.validator.addMethod("time", function(value, element) {\r
338         return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);\r
339 }, "Please enter a valid time, between 00:00 and 23:59");\r
340 jQuery.validator.addMethod("time12h", function(value, element) {\r
341         return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);\r
342 }, "Please enter a valid time in 12-hour am/pm format");\r
343 \r
344 /**\r
345  * matches US phone number format\r
346  *\r
347  * where the area code may not start with 1 and the prefix may not start with 1\r
348  * allows '-' or ' ' as a separator and allows parens around area code\r
349  * some people may want to put a '1' in front of their number\r
350  *\r
351  * 1(212)-999-2345 or\r
352  * 212 999 2344 or\r
353  * 212-999-0983\r
354  *\r
355  * but not\r
356  * 111-123-5434\r
357  * and not\r
358  * 212 123 4567\r
359  */\r
360 jQuery.validator.addMethod("phoneUS", function(phone_number, element) {\r
361         phone_number = phone_number.replace(/\s+/g, "");\r
362         return this.optional(element) || phone_number.length > 9 &&\r
363                 phone_number.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);\r
364 }, "Please specify a valid phone number");\r
365 \r
366 jQuery.validator.addMethod('phoneUK', function(phone_number, element) {\r
367         phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');\r
368         return this.optional(element) || phone_number.length > 9 &&\r
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})$/);\r
370 }, 'Please specify a valid phone number');\r
371 \r
372 jQuery.validator.addMethod('mobileUK', function(phone_number, element) {\r
373         phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');\r
374         return this.optional(element) || phone_number.length > 9 &&\r
375                 phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/);\r
376 }, 'Please specify a valid mobile number');\r
377 \r
378 //Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers\r
379 jQuery.validator.addMethod('phonesUK', function(phone_number, element) {\r
380         phone_number = phone_number.replace(/\(|\)|\s+|-/g,'');\r
381         return this.optional(element) || phone_number.length > 9 &&\r
382                 phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/);\r
383 }, 'Please specify a valid uk phone number');\r
384 // On the above three UK functions, do the following server side processing:\r
385 //  Compare original input with this RegEx pattern:\r
386 //   ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$\r
387 //  Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\r
388 //  Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\r
389 // A number of very detailed GB telephone number RegEx patterns can also be found at:\r
390 // http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\r
391 \r
392 // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)\r
393 jQuery.validator.addMethod('postcodeUK', function(value, element) {\r
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);\r
395 }, 'Please specify a valid UK postcode');\r
396 \r
397 // TODO check if value starts with <, otherwise don't try stripping anything\r
398 jQuery.validator.addMethod("strippedminlength", function(value, element, param) {\r
399         return jQuery(value).text().length >= param;\r
400 }, jQuery.validator.format("Please enter at least {0} characters"));\r
401 \r
402 // same as email, but TLD is optional\r
403 jQuery.validator.addMethod("email2", function(value, element, param) {\r
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);\r
405 }, jQuery.validator.messages.email);\r
406 \r
407 // same as url, but TLD is optional\r
408 jQuery.validator.addMethod("url2", function(value, element, param) {\r
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);\r
410 }, jQuery.validator.messages.url);\r
411 \r
412 // NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator\r
413 // Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0\r
414 // Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)\r
415 jQuery.validator.addMethod("creditcardtypes", function(value, element, param) {\r
416         if (/[^0-9\-]+/.test(value)) {\r
417                 return false;\r
418         }\r
419 \r
420         value = value.replace(/\D/g, "");\r
421 \r
422         var validTypes = 0x0000;\r
423 \r
424         if (param.mastercard) {\r
425                 validTypes |= 0x0001;\r
426         }\r
427         if (param.visa) {\r
428                 validTypes |= 0x0002;\r
429         }\r
430         if (param.amex) {\r
431                 validTypes |= 0x0004;\r
432         }\r
433         if (param.dinersclub) {\r
434                 validTypes |= 0x0008;\r
435         }\r
436         if (param.enroute) {\r
437                 validTypes |= 0x0010;\r
438         }\r
439         if (param.discover) {\r
440                 validTypes |= 0x0020;\r
441         }\r
442         if (param.jcb) {\r
443                 validTypes |= 0x0040;\r
444         }\r
445         if (param.unknown) {\r
446                 validTypes |= 0x0080;\r
447         }\r
448         if (param.all) {\r
449                 validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\r
450         }\r
451         if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard\r
452                 return value.length === 16;\r
453         }\r
454         if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\r
455                 return value.length === 16;\r
456         }\r
457         if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex\r
458                 return value.length === 15;\r
459         }\r
460         if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub\r
461                 return value.length === 14;\r
462         }\r
463         if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute\r
464                 return value.length === 15;\r
465         }\r
466         if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\r
467                 return value.length === 16;\r
468         }\r
469         if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\r
470                 return value.length === 16;\r
471         }\r
472         if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\r
473                 return value.length === 15;\r
474         }\r
475         if (validTypes & 0x0080) { //unknown\r
476                 return true;\r
477         }\r
478         return false;\r
479 }, "Please enter a valid credit card number.");\r
480 \r
481 jQuery.validator.addMethod("ipv4", function(value, element, param) {\r
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);\r
483 }, "Please enter a valid IP v4 address.");\r
484 \r
485 jQuery.validator.addMethod("ipv6", function(value, element, param) {\r
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);\r
487 }, "Please enter a valid IP v6 address.");\r
488 \r
489 /**\r
490 * Return true if the field value matches the given format RegExp\r
491 *\r
492 * @example jQuery.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)\r
493 * @result true\r
494 *\r
495 * @example jQuery.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)\r
496 * @result false\r
497 *\r
498 * @name jQuery.validator.methods.pattern\r
499 * @type Boolean\r
500 * @cat Plugins/Validate/Methods\r
501 */\r
502 jQuery.validator.addMethod("pattern", function(value, element, param) {\r
503         if (this.optional(element)) {\r
504                 return true;\r
505         }\r
506         if (typeof param === 'string') {\r
507                 param = new RegExp('^(?:' + param + ')$');\r
508         }\r
509         return param.test(value);\r
510 }, "Invalid format.");\r
511 \r
512 \r
513 /*\r
514  * Lets you say "at least X inputs that match selector Y must be filled."\r
515  *\r
516  * The end result is that neither of these inputs:\r
517  *\r
518  *  <input class="productinfo" name="partnumber">\r
519  *  <input class="productinfo" name="description">\r
520  *\r
521  *  ...will validate unless at least one of them is filled.\r
522  *\r
523  * partnumber:  {require_from_group: [1,".productinfo"]},\r
524  * description: {require_from_group: [1,".productinfo"]}\r
525  *\r
526  */\r
527 jQuery.validator.addMethod("require_from_group", function(value, element, options) {\r
528         var validator = this;\r
529         var selector = options[1];\r
530         var validOrNot = $(selector, element.form).filter(function() {\r
531                 return validator.elementValue(this);\r
532         }).length >= options[0];\r
533 \r
534         if(!$(element).data('being_validated')) {\r
535                 var fields = $(selector, element.form);\r
536                 fields.data('being_validated', true);\r
537                 fields.valid();\r
538                 fields.data('being_validated', false);\r
539         }\r
540         return validOrNot;\r
541 }, jQuery.format("Please fill at least {0} of these fields."));\r
542 \r
543 /*\r
544  * Lets you say "either at least X inputs that match selector Y must be filled,\r
545  * OR they must all be skipped (left blank)."\r
546  *\r
547  * The end result, is that none of these inputs:\r
548  *\r
549  *  <input class="productinfo" name="partnumber">\r
550  *  <input class="productinfo" name="description">\r
551  *  <input class="productinfo" name="color">\r
552  *\r
553  *  ...will validate unless either at least two of them are filled,\r
554  *  OR none of them are.\r
555  *\r
556  * partnumber:  {skip_or_fill_minimum: [2,".productinfo"]},\r
557  *  description: {skip_or_fill_minimum: [2,".productinfo"]},\r
558  * color:       {skip_or_fill_minimum: [2,".productinfo"]}\r
559  *\r
560  */\r
561 jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {\r
562         var validator = this,\r
563                 numberRequired = options[0],\r
564                 selector = options[1];\r
565         var numberFilled = $(selector, element.form).filter(function() {\r
566                 return validator.elementValue(this);\r
567         }).length;\r
568         var valid = numberFilled >= numberRequired || numberFilled === 0;\r
569 \r
570         if(!$(element).data('being_validated')) {\r
571                 var fields = $(selector, element.form);\r
572                 fields.data('being_validated', true);\r
573                 fields.valid();\r
574                 fields.data('being_validated', false);\r
575         }\r
576         return valid;\r
577 }, jQuery.format("Please either skip these fields or fill at least {0} of them."));\r
578 \r
579 // Accept a value from a file input based on a required mimetype\r
580 jQuery.validator.addMethod("accept", function(value, element, param) {\r
581         // Split mime on commas in case we have multiple types we can accept\r
582         var typeParam = typeof param === "string" ? param.replace(/\s/g, '').replace(/,/g, '|') : "image/*",\r
583         optionalValue = this.optional(element),\r
584         i, file;\r
585 \r
586         // Element is optional\r
587         if (optionalValue) {\r
588                 return optionalValue;\r
589         }\r
590 \r
591         if ($(element).attr("type") === "file") {\r
592                 // If we are using a wildcard, make it regex friendly\r
593                 typeParam = typeParam.replace(/\*/g, ".*");\r
594 \r
595                 // Check if the element has a FileList before checking each file\r
596                 if (element.files && element.files.length) {\r
597                         for (i = 0; i < element.files.length; i++) {\r
598                                 file = element.files[i];\r
599 \r
600                                 // Grab the mimetype from the loaded file, verify it matches\r
601                                 if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {\r
602                                         return false;\r
603                                 }\r
604                         }\r
605                 }\r
606         }\r
607 \r
608         // Either return true because we've validated each file, or because the\r
609         // browser does not support element.files and the FileList feature\r
610         return true;\r
611 }, jQuery.format("Please enter a value with a valid mimetype."));\r
612 \r
613 // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept\r
614 jQuery.validator.addMethod("extension", function(value, element, param) {\r
615         param = typeof param === "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";\r
616         return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));\r
617 }, jQuery.format("Please enter a value with a valid extension."));\r