zipCode.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. (function($) {
  2. $.fn.bootstrapValidator.i18n.zipCode = $.extend($.fn.bootstrapValidator.i18n.zipCode || {}, {
  3. 'default': 'Please enter a valid postal code',
  4. countryNotSupported: 'The country code %s is not supported',
  5. country: 'Please enter a valid postal code in %s',
  6. countries: {
  7. AT: 'Austria',
  8. BR: 'Brazil',
  9. CA: 'Canada',
  10. CH: 'Switzerland',
  11. CZ: 'Czech Republic',
  12. DE: 'Germany',
  13. DK: 'Denmark',
  14. FR: 'France',
  15. GB: 'United Kingdom',
  16. IE: 'Ireland',
  17. IT: 'Italy',
  18. MA: 'Morocco',
  19. NL: 'Netherlands',
  20. PT: 'Portugal',
  21. RO: 'Romania',
  22. RU: 'Russia',
  23. SE: 'Sweden',
  24. SG: 'Singapore',
  25. SK: 'Slovakia',
  26. US: 'USA'
  27. }
  28. });
  29. $.fn.bootstrapValidator.validators.zipCode = {
  30. html5Attributes: {
  31. message: 'message',
  32. country: 'country'
  33. },
  34. COUNTRY_CODES: [ 'AT', 'BR', 'CA', 'CH', 'CZ', 'DE', 'DK', 'FR', 'GB', 'IE', 'IT', 'MA', 'NL', 'PT', 'RO', 'RU', 'SE', 'SG', 'SK', 'US'],
  35. /**
  36. * Return true if and only if the input value is a valid country zip code
  37. *
  38. * @param {BootstrapValidator} validator The validator plugin instance
  39. * @param {jQuery} $field Field element
  40. * @param {Object} options Consist of key:
  41. * - message: The invalid message
  42. * - country: The country
  43. *
  44. * The country can be defined by:
  45. * - An ISO 3166 country code
  46. * - Name of field which its value defines the country code
  47. * - Name of callback function that returns the country code
  48. * - A callback function that returns the country code
  49. *
  50. * callback: function(value, validator, $field) {
  51. * // value is the value of field
  52. * // validator is the BootstrapValidator instance
  53. * // $field is jQuery element representing the field
  54. * }
  55. *
  56. * @returns {Boolean|Object}
  57. */
  58. validate: function(validator, $field, options) {
  59. var value = $field.val();
  60. if (value === '' || !options.country) {
  61. return true;
  62. }
  63. var country = options.country;
  64. if (typeof country !== 'string' || $.inArray(country, this.COUNTRY_CODES) === -1) {
  65. // Try to determine the country
  66. country = validator.getDynamicOption($field, country);
  67. }
  68. if (!country || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
  69. return { valid: false, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.zipCode.countryNotSupported, country) };
  70. }
  71. var isValid = false;
  72. country = country.toUpperCase();
  73. switch (country) {
  74. // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Austria
  75. case 'AT':
  76. isValid = /^([1-9]{1})(\d{3})$/.test(value);
  77. break;
  78. case 'BR':
  79. isValid = /^(\d{2})([\.]?)(\d{3})([\-]?)(\d{3})$/.test(value);
  80. break;
  81. case 'CA':
  82. isValid = /^(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|X|Y){1}[0-9]{1}(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|W|X|Y|Z){1}\s?[0-9]{1}(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|W|X|Y|Z){1}[0-9]{1}$/i.test(value);
  83. break;
  84. case 'CH':
  85. isValid = /^([1-9]{1})(\d{3})$/.test(value);
  86. break;
  87. case 'CZ':
  88. // Test: http://regexr.com/39hhr
  89. isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
  90. break;
  91. // http://stackoverflow.com/questions/7926687/regular-expression-german-zip-codes
  92. case 'DE':
  93. isValid = /^(?!01000|99999)(0[1-9]\d{3}|[1-9]\d{4})$/.test(value);
  94. break;
  95. case 'DK':
  96. isValid = /^(DK(-|\s)?)?\d{4}$/i.test(value);
  97. break;
  98. // http://en.wikipedia.org/wiki/Postal_codes_in_France
  99. case 'FR':
  100. isValid = /^[0-9]{5}$/i.test(value);
  101. break;
  102. case 'GB':
  103. isValid = this._gb(value);
  104. break;
  105. // http://www.eircode.ie/docs/default-source/Common/prepare-your-business-for-eircode---published-v2.pdf?sfvrsn=2
  106. // Test: http://refiddle.com/1kpl
  107. case 'IE':
  108. isValid = /^(D6W|[ACDEFHKNPRTVWXY]\d{2})\s[0-9ACDEFHKNPRTVWXY]{4}$/.test(value);
  109. break;
  110. // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Italy
  111. case 'IT':
  112. isValid = /^(I-|IT-)?\d{5}$/i.test(value);
  113. break;
  114. // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Morocco
  115. case 'MA':
  116. isValid = /^[1-9][0-9]{4}$/i.test(value);
  117. break;
  118. // http://en.wikipedia.org/wiki/Postal_codes_in_the_Netherlands
  119. case 'NL':
  120. isValid = /^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i.test(value);
  121. break;
  122. // Test: http://refiddle.com/1l2t
  123. case 'PT':
  124. isValid = /^[1-9]\d{3}-\d{3}$/.test(value);
  125. break;
  126. case 'RO':
  127. isValid = /^(0[1-8]{1}|[1-9]{1}[0-5]{1})?[0-9]{4}$/i.test(value);
  128. break;
  129. case 'RU':
  130. isValid = /^[0-9]{6}$/i.test(value);
  131. break;
  132. case 'SE':
  133. isValid = /^(S-)?\d{3}\s?\d{2}$/i.test(value);
  134. break;
  135. case 'SG':
  136. isValid = /^([0][1-9]|[1-6][0-9]|[7]([0-3]|[5-9])|[8][0-2])(\d{4})$/i.test(value);
  137. break;
  138. case 'SK':
  139. // Test: http://regexr.com/39hhr
  140. isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
  141. break;
  142. case 'US':
  143. /* falls through */
  144. default:
  145. isValid = /^\d{4,5}([\-]?\d{4})?$/.test(value);
  146. break;
  147. }
  148. return {
  149. valid: isValid,
  150. message: $.fn.bootstrapValidator.helpers.format(options.message || $.fn.bootstrapValidator.i18n.zipCode.country, $.fn.bootstrapValidator.i18n.zipCode.countries[country])
  151. };
  152. },
  153. /**
  154. * Validate United Kingdom postcode
  155. * Examples:
  156. * - Standard: EC1A 1BB, W1A 1HQ, M1 1AA, B33 8TH, CR2 6XH, DN55 1PT
  157. * - Special cases:
  158. * AI-2640, ASCN 1ZZ, GIR 0AA
  159. *
  160. * @see http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
  161. * @param {String} value The postcode
  162. * @returns {Boolean}
  163. */
  164. _gb: function(value) {
  165. var firstChar = '[ABCDEFGHIJKLMNOPRSTUWYZ]', // Does not accept QVX
  166. secondChar = '[ABCDEFGHKLMNOPQRSTUVWXY]', // Does not accept IJZ
  167. thirdChar = '[ABCDEFGHJKPMNRSTUVWXY]',
  168. fourthChar = '[ABEHMNPRVWXY]',
  169. fifthChar = '[ABDEFGHJLNPQRSTUWXYZ]',
  170. regexps = [
  171. // AN NAA, ANN NAA, AAN NAA, AANN NAA format
  172. new RegExp('^(' + firstChar + '{1}' + secondChar + '?[0-9]{1,2})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
  173. // ANA NAA
  174. new RegExp('^(' + firstChar + '{1}[0-9]{1}' + thirdChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
  175. // AANA NAA
  176. new RegExp('^(' + firstChar + '{1}' + secondChar + '{1}?[0-9]{1}' + fourthChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
  177. new RegExp('^(BF1)(\\s*)([0-6]{1}[ABDEFGHJLNPQRST]{1}[ABDEFGHJLNPQRSTUWZYZ]{1})$', 'i'), // BFPO postcodes
  178. /^(GIR)(\s*)(0AA)$/i, // Special postcode GIR 0AA
  179. /^(BFPO)(\s*)([0-9]{1,4})$/i, // Standard BFPO numbers
  180. /^(BFPO)(\s*)(c\/o\s*[0-9]{1,3})$/i, // c/o BFPO numbers
  181. /^([A-Z]{4})(\s*)(1ZZ)$/i, // Overseas Territories
  182. /^(AI-2640)$/i // Anguilla
  183. ];
  184. for (var i = 0; i < regexps.length; i++) {
  185. if (regexps[i].test(value)) {
  186. return true;
  187. }
  188. }
  189. return false;
  190. }
  191. };
  192. }(jQuery));