PageSourceSearch

https://www.zoeblueprint.com/validation/additional-methods.js

js zoeblueprint.com collected 2026-10-02 01:51:20 UTC 41,971 bytes, 966 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.