bootstrap-validator-rails 0.5.0.2 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZmE5ODE3NGI5MzI5YWU4M2EwMDQ4MDNhOTQyYTE1YzQ2ZWM0YTcxNg==
5
- data.tar.gz: !binary |-
6
- ZGI0OGQzNTgwMDRmOGVjZjAxNjRhYTRhNzg1YTg0YzI2NWM2ZDkwYQ==
2
+ SHA1:
3
+ metadata.gz: 993cafc397ed0f6251ab9e179ae990fdf959b23d
4
+ data.tar.gz: fba1ab25acc15ed0de59376b08cb6e951a9368e3
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YWFlNDMyNjJjNmFmMTRhNWRkODI3MDY0OGU1YzZlZTZiYmExNmVhNjllMDRi
10
- YzdiOWFlMjYzYjg1YWQwZjQ3ZmVmMzQ2YTQ0YTExODJlMWRjNTFmZmM4NDlm
11
- NDU4NDVjMTQxOWJkNzI0NzExMTk1YmMxYmVmMzk1NTliMzcwY2I=
12
- data.tar.gz: !binary |-
13
- ODc0NGQ0ZTA1ZWJmZWVkMjA0MDhlYjcxMzQ5Njg2MmY0Yjk5YTAyMzA2MGNm
14
- YmY3MWY3MGE2ZDhhMDU0MzViZWEyMWY1M2Y4ZGM2OTVmNTMxMjBiNjVhY2U0
15
- YzM1NTk2NmE5NjExY2RmNzFhZjU3ZDhjYjhlODliOTExZGU4NzI=
6
+ metadata.gz: a4443faf6e9e915226f57ba38f9dba8daa324a9db901482d668e01f6651e9ca24d639342c1118d5b2be0d6eef84d2372f7f0e9ee0c0ff1d1d7de48de41254d86
7
+ data.tar.gz: 0e51a2bc522d55015c07c83dfaba355b933776b79d12716b94c7601e0d025d5a8c9b9185db9406c32e3f854716dd53e10f8443f38764d1825c5bc9f84591c3a3
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- bootstrap-validator-rails
2
- =========================
1
+ bootstrap-validator-rails (0.5.1)
2
+ =================================
3
3
 
4
4
  Gem version of bootstrapvalidator JavaScript library = a jQuery based field validator for Twitter Bootstrap 3.
5
5
 
@@ -1,6 +1,6 @@
1
1
  module BootstrapValidatorRails
2
2
  module Rails
3
- VERSION = "0.5.0.2"
4
- BOOTSTRAP_VALIDATOR_VERSION = "0.5.0"
3
+ VERSION = "0.5.1"
4
+ BOOTSTRAP_VALIDATOR_VERSION = "0.5.1"
5
5
  end
6
6
  end
@@ -2,7 +2,7 @@
2
2
  * BootstrapValidator (http://bootstrapvalidator.com)
3
3
  * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
4
4
  *
5
- * @version v0.5.0, built on 2014-07-14 4:31:02 PM
5
+ * @version v0.5.1, built on 2014-08-22 4:55:09 PM
6
6
  * @author https://twitter.com/nghuuphuoc
7
7
  * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc
8
8
  * @license MIT
@@ -14,6 +14,7 @@
14
14
 
15
15
  this.$invalidFields = $([]); // Array of invalid fields
16
16
  this.$submitButton = null; // The submit button which is clicked to submit form
17
+ this.$hiddenButton = null;
17
18
 
18
19
  // Validating status
19
20
  this.STATUS_NOT_VALIDATED = 'NOT_VALIDATED';
@@ -68,6 +69,19 @@
68
69
  valid: this.$form.attr('data-bv-feedbackicons-valid'),
69
70
  invalid: this.$form.attr('data-bv-feedbackicons-invalid'),
70
71
  validating: this.$form.attr('data-bv-feedbackicons-validating')
72
+ },
73
+ events: {
74
+ formInit: this.$form.attr('data-bv-events-form-init'),
75
+ formError: this.$form.attr('data-bv-events-form-error'),
76
+ formSuccess: this.$form.attr('data-bv-events-form-success'),
77
+ fieldAdded: this.$form.attr('data-bv-events-field-added'),
78
+ fieldRemoved: this.$form.attr('data-bv-events-field-removed'),
79
+ fieldInit: this.$form.attr('data-bv-events-field-init'),
80
+ fieldError: this.$form.attr('data-bv-events-field-error'),
81
+ fieldSuccess: this.$form.attr('data-bv-events-field-success'),
82
+ fieldStatus: this.$form.attr('data-bv-events-field-status'),
83
+ validatorError: this.$form.attr('data-bv-events-validator-error'),
84
+ validatorSuccess: this.$form.attr('data-bv-events-validator-success')
71
85
  }
72
86
  };
73
87
 
@@ -98,23 +112,43 @@
98
112
  });
99
113
 
100
114
  this.options = $.extend(true, this.options, options);
115
+
116
+ // When pressing Enter on any field in the form, the first submit button will do its job.
117
+ // The form then will be submitted.
118
+ // I create a first hidden submit button
119
+ this.$hiddenButton = $('<button/>')
120
+ .attr('type', 'submit')
121
+ .prependTo(this.$form)
122
+ .addClass('bv-hidden-submit')
123
+ .css({ display: 'none', width: 0, height: 0 });
124
+
125
+ this.$form
126
+ .on('click.bv', '[type="submit"]', function(e) {
127
+ // Don't perform validation when clicking on the submit button/input
128
+ // which aren't defined by the 'submitButtons' option
129
+ var $button = $(e.target).eq(0);
130
+ if (that.options.submitButtons && !$button.is(that.options.submitButtons) && !$button.is(that.$hiddenButton)) {
131
+ that.$form.off('submit.bv').submit();
132
+ }
133
+ });
134
+
101
135
  for (var field in this.options.fields) {
102
136
  this._initField(field);
103
137
  }
104
138
 
105
- this.$form.trigger($.Event('init.form.bv'), {
139
+ this.$form.trigger($.Event(this.options.events.formInit), {
106
140
  bv: this,
107
141
  options: this.options
108
142
  });
109
143
 
110
144
  // Prepare the events
111
145
  if (this.options.onSuccess) {
112
- this.$form.on('success.form.bv', function(e) {
146
+ this.$form.on(this.options.events.formSuccess, function(e) {
113
147
  $.fn.bootstrapValidator.helpers.call(that.options.onSuccess, [e]);
114
148
  });
115
149
  }
116
150
  if (this.options.onError) {
117
- this.$form.on('error.form.bv', function(e) {
151
+ this.$form.on(this.options.events.formError, function(e) {
118
152
  $.fn.bootstrapValidator.helpers.call(that.options.onError, [e]);
119
153
  });
120
154
  }
@@ -277,12 +311,12 @@
277
311
 
278
312
  // Prepare the validator events
279
313
  if (this.options.fields[field].validators[validatorName].onSuccess) {
280
- $field.on('success.validator.bv', function(e, data) {
314
+ $field.on(this.options.events.validatorSuccess, function(e, data) {
281
315
  $.fn.bootstrapValidator.helpers.call(that.options.fields[field].validators[validatorName].onSuccess, [e, data]);
282
316
  });
283
317
  }
284
318
  if (this.options.fields[field].validators[validatorName].onError) {
285
- $field.on('error.validator.bv', function(e, data) {
319
+ $field.on(this.options.events.validatorError, function(e, data) {
286
320
  $.fn.bootstrapValidator.helpers.call(that.options.fields[field].validators[validatorName].onError, [e, data]);
287
321
  });
288
322
  }
@@ -300,9 +334,18 @@
300
334
  .css('display', 'none')
301
335
  .addClass('form-control-feedback')
302
336
  .attr('data-bv-icon-for', field)
303
- // Place it after the label containing the checkbox/radio
304
- // so when clicking the icon, it doesn't effect to the checkbox/radio element
305
- .insertAfter(('checkbox' === type || 'radio' === type) ? $field.parent() : $field);
337
+ .insertAfter($field);
338
+
339
+ // Place it after the container of checkbox/radio
340
+ // so when clicking the icon, it doesn't effect to the checkbox/radio element
341
+ if ('checkbox' === type || 'radio' === type) {
342
+ var $fieldParent = $field.parent();
343
+ if ($fieldParent.hasClass(type)) {
344
+ $icon.insertAfter($fieldParent);
345
+ } else if ($fieldParent.parent().hasClass(type)) {
346
+ $icon.insertAfter($fieldParent.parent());
347
+ }
348
+ }
306
349
 
307
350
  // The feedback icon does not render correctly if there is no label
308
351
  // https://github.com/twbs/bootstrap/issues/12873
@@ -321,17 +364,17 @@
321
364
 
322
365
  // Prepare the events
323
366
  if (this.options.fields[field].onSuccess) {
324
- fields.on('success.field.bv', function(e, data) {
367
+ fields.on(this.options.events.fieldSuccess, function(e, data) {
325
368
  $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onSuccess, [e, data]);
326
369
  });
327
370
  }
328
371
  if (this.options.fields[field].onError) {
329
- fields.on('error.field.bv', function(e, data) {
372
+ fields.on(this.options.events.fieldError, function(e, data) {
330
373
  $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onError, [e, data]);
331
374
  });
332
375
  }
333
376
  if (this.options.fields[field].onStatus) {
334
- fields.on('status.field.bv', function(e, data) {
377
+ fields.on(this.options.events.fieldStatus, function(e, data) {
335
378
  $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onStatus, [e, data]);
336
379
  });
337
380
  }
@@ -357,7 +400,7 @@
357
400
  break;
358
401
  }
359
402
 
360
- fields.trigger($.Event('init.field.bv'), {
403
+ fields.trigger($.Event(this.options.events.fieldInit), {
361
404
  bv: this,
362
405
  field: field,
363
406
  element: fields
@@ -425,7 +468,7 @@
425
468
  */
426
469
  _submit: function() {
427
470
  var isValid = this.isValid(),
428
- eventType = isValid ? 'success.form.bv' : 'error.form.bv',
471
+ eventType = isValid ? this.options.events.formSuccess : this.options.events.formError,
429
472
  e = $.Event(eventType);
430
473
 
431
474
  this.$form.trigger(e);
@@ -588,10 +631,10 @@
588
631
  if (validatorName) {
589
632
  switch ($field.data('bv.result.' + validatorName)) {
590
633
  case this.STATUS_INVALID:
591
- $field.trigger($.Event('error.validator.bv'), data);
634
+ $field.trigger($.Event(this.options.events.validatorError), data);
592
635
  break;
593
636
  case this.STATUS_VALID:
594
- $field.trigger($.Event('success.validator.bv'), data);
637
+ $field.trigger($.Event(this.options.events.validatorSuccess), data);
595
638
  break;
596
639
  default:
597
640
  break;
@@ -619,14 +662,14 @@
619
662
  // Remove from the list of invalid fields
620
663
  this.$invalidFields = this.$invalidFields.not($field);
621
664
 
622
- $field.trigger($.Event('success.field.bv'), data);
665
+ $field.trigger($.Event(this.options.events.fieldSuccess), data);
623
666
  }
624
667
  // If all validators are completed and there is at least one validator which doesn't pass
625
668
  else if (counter[this.STATUS_NOT_VALIDATED] === 0 && counter[this.STATUS_VALIDATING] === 0 && counter[this.STATUS_INVALID] > 0) {
626
669
  // Add to the list of invalid fields
627
670
  this.$invalidFields = this.$invalidFields.add($field);
628
671
 
629
- $field.trigger($.Event('error.field.bv'), data);
672
+ $field.trigger($.Event(this.options.events.fieldError), data);
630
673
  }
631
674
  },
632
675
 
@@ -956,7 +999,7 @@
956
999
  }
957
1000
 
958
1001
  // Trigger an event
959
- $field.trigger($.Event('status.field.bv'), {
1002
+ $field.trigger($.Event(this.options.events.fieldStatus), {
960
1003
  bv: this,
961
1004
  field: field,
962
1005
  element: $field,
@@ -1258,7 +1301,7 @@
1258
1301
 
1259
1302
  this.disableSubmitButtons(false);
1260
1303
  // Trigger an event
1261
- this.$form.trigger($.Event('added.field.bv'), {
1304
+ this.$form.trigger($.Event(this.options.events.fieldAdded), {
1262
1305
  field: field,
1263
1306
  element: fields,
1264
1307
  options: this.options.fields[field]
@@ -1314,7 +1357,7 @@
1314
1357
 
1315
1358
  this.disableSubmitButtons(false);
1316
1359
  // Trigger an event
1317
- this.$form.trigger($.Event('removed.field.bv'), {
1360
+ this.$form.trigger($.Event(this.options.events.fieldRemoved), {
1318
1361
  field: field,
1319
1362
  element: fields
1320
1363
  });
@@ -1464,7 +1507,7 @@
1464
1507
  }
1465
1508
  // ... return value of callback
1466
1509
  else {
1467
- return $.fn.bootstrapValidator.helpers.call(option, [value, this, $field]);
1510
+ return $.fn.bootstrapValidator.helpers.call(option, [value, this, $field]) || option;
1468
1511
  }
1469
1512
  }
1470
1513
 
@@ -1522,15 +1565,16 @@
1522
1565
  }
1523
1566
  }
1524
1567
 
1525
- // Enable submit buttons
1526
- this.disableSubmitButtons(false);
1568
+ this.disableSubmitButtons(false); // Enable submit buttons
1569
+ this.$hiddenButton.remove(); // Remove the hidden button
1527
1570
 
1528
1571
  this.$form
1529
1572
  .removeClass(this.options.elementClass)
1530
1573
  .off('.bv')
1531
1574
  .removeData('bootstrapValidator')
1532
1575
  // Remove generated hidden elements
1533
- .find('[data-bv-submit-hidden]').remove();
1576
+ .find('[data-bv-submit-hidden]').remove().end()
1577
+ .find('[type="submit"]').off('click.bv');
1534
1578
  }
1535
1579
  };
1536
1580
 
@@ -1638,7 +1682,23 @@
1638
1682
  live: 'enabled',
1639
1683
 
1640
1684
  // Map the field name with validator rules
1641
- fields: null
1685
+ fields: null,
1686
+
1687
+ // Use custom event name to avoid window.onerror being invoked by jQuery
1688
+ // See https://github.com/nghuuphuoc/bootstrapvalidator/issues/630
1689
+ events: {
1690
+ formInit: 'init.form.bv',
1691
+ formError: 'error.form.bv',
1692
+ formSuccess: 'success.form.bv',
1693
+ fieldAdded: 'added.field.bv',
1694
+ fieldRemoved: 'removed.field.bv',
1695
+ fieldInit: 'init.field.bv',
1696
+ fieldError: 'error.field.bv',
1697
+ fieldSuccess: 'success.field.bv',
1698
+ fieldStatus: 'status.field.bv',
1699
+ validatorError: 'error.validator.bv',
1700
+ validatorSuccess: 'success.validator.bv'
1701
+ }
1642
1702
  };
1643
1703
 
1644
1704
  // Available validators
@@ -1673,7 +1733,8 @@
1673
1733
  for (var i = 0; i < ns.length; i++) {
1674
1734
  context = context[ns[i]];
1675
1735
  }
1676
- return context[func].apply(this, args);
1736
+
1737
+ return (typeof context[func] === 'undefined') ? null : context[func].apply(this, args);
1677
1738
  }
1678
1739
  },
1679
1740
 
@@ -1711,6 +1772,9 @@
1711
1772
  if (isNaN(year) || isNaN(month) || isNaN(day)) {
1712
1773
  return false;
1713
1774
  }
1775
+ if (day.length > 2 || month.length > 2 || year.length > 4) {
1776
+ return false;
1777
+ }
1714
1778
 
1715
1779
  day = parseInt(day, 10);
1716
1780
  month = parseInt(month, 10);
@@ -1876,10 +1940,12 @@
1876
1940
  if (value === '') {
1877
1941
  return true;
1878
1942
  }
1943
+ if (!$.isNumeric(value)) {
1944
+ return false;
1945
+ }
1879
1946
 
1880
1947
  var min = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min),
1881
1948
  max = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max);
1882
-
1883
1949
  value = parseFloat(value);
1884
1950
  return (options.inclusive === true || options.inclusive === undefined)
1885
1951
  ? {
@@ -2313,6 +2379,11 @@
2313
2379
 
2314
2380
  options.format = options.format || 'MM/DD/YYYY';
2315
2381
 
2382
+ // #683: Force the format to YYYY-MM-DD as the default browser behaviour when using type="date" attribute
2383
+ if ($field.attr('type') === 'date') {
2384
+ options.format = 'YYYY-MM-DD';
2385
+ }
2386
+
2316
2387
  var formats = options.format.split(' '),
2317
2388
  dateFormat = formats[0],
2318
2389
  timeFormat = (formats.length > 1) ? formats[1] : null,
@@ -2345,7 +2416,7 @@
2345
2416
  month = date[$.inArray('MM', dateFormat)],
2346
2417
  day = date[$.inArray('DD', dateFormat)];
2347
2418
 
2348
- if (!year || !month || !day) {
2419
+ if (!year || !month || !day || year.length !== 4) {
2349
2420
  return false;
2350
2421
  }
2351
2422
 
@@ -2365,24 +2436,33 @@
2365
2436
 
2366
2437
  // Validate seconds
2367
2438
  if (seconds) {
2439
+ if (isNaN(seconds) || seconds.length > 2) {
2440
+ return false;
2441
+ }
2368
2442
  seconds = parseInt(seconds, 10);
2369
- if (isNaN(seconds) || seconds < 0 || seconds > 60) {
2443
+ if (seconds < 0 || seconds > 60) {
2370
2444
  return false;
2371
2445
  }
2372
2446
  }
2373
2447
 
2374
2448
  // Validate hours
2375
2449
  if (hours) {
2450
+ if (isNaN(hours) || hours.length > 2) {
2451
+ return false;
2452
+ }
2376
2453
  hours = parseInt(hours, 10);
2377
- if (isNaN(hours) || hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
2454
+ if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
2378
2455
  return false;
2379
2456
  }
2380
2457
  }
2381
2458
 
2382
2459
  // Validate minutes
2383
2460
  if (minutes) {
2461
+ if (isNaN(minutes) || minutes.length > 2) {
2462
+ return false;
2463
+ }
2384
2464
  minutes = parseInt(minutes, 10);
2385
- if (isNaN(minutes) || minutes < 0 || minutes > 59) {
2465
+ if (minutes < 0 || minutes > 59) {
2386
2466
  return false;
2387
2467
  }
2388
2468
  }
@@ -2421,7 +2501,7 @@
2421
2501
  }
2422
2502
 
2423
2503
  var compareWith = validator.getFieldElements(options.field);
2424
- if (compareWith === null) {
2504
+ if (compareWith === null || compareWith.length === 0) {
2425
2505
  return true;
2426
2506
  }
2427
2507
 
@@ -2582,7 +2662,7 @@
2582
2662
  }
2583
2663
 
2584
2664
  // Check file type
2585
- if (types && $.inArray(files[i].type.toLowerCase(), types) === -1) {
2665
+ if (files[i].type && types && $.inArray(files[i].type.toLowerCase(), types) === -1) {
2586
2666
  return false;
2587
2667
  }
2588
2668
  }
@@ -2612,8 +2692,9 @@
2612
2692
  },
2613
2693
 
2614
2694
  enableByHtml5: function($field) {
2615
- var min = $field.attr('min');
2616
- if (min) {
2695
+ var type = $field.attr('type'),
2696
+ min = $field.attr('min');
2697
+ if (min && type !== 'date') {
2617
2698
  return {
2618
2699
  value: min
2619
2700
  };
@@ -2643,9 +2724,11 @@
2643
2724
  if (value === '') {
2644
2725
  return true;
2645
2726
  }
2727
+ if (!$.isNumeric(value)) {
2728
+ return false;
2729
+ }
2646
2730
 
2647
2731
  var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value);
2648
-
2649
2732
  value = parseFloat(value);
2650
2733
  return (options.inclusive === true || options.inclusive === undefined)
2651
2734
  ? {
@@ -2846,85 +2929,85 @@
2846
2929
  // http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf
2847
2930
  // http://en.wikipedia.org/wiki/International_Bank_Account_Number#IBAN_formats_by_country
2848
2931
  REGEX: {
2849
- 'AD': 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}', // Andorra
2850
- 'AE': 'AE[0-9]{2}[0-9]{3}[0-9]{16}', // United Arab Emirates
2851
- 'AL': 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}', // Albania
2852
- 'AO': 'AO[0-9]{2}[0-9]{21}', // Angola
2853
- 'AT': 'AT[0-9]{2}[0-9]{5}[0-9]{11}', // Austria
2854
- 'AZ': 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}', // Azerbaijan
2855
- 'BA': 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}', // Bosnia and Herzegovina
2856
- 'BE': 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}', // Belgium
2857
- 'BF': 'BF[0-9]{2}[0-9]{23}', // Burkina Faso
2858
- 'BG': 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}', // Bulgaria
2859
- 'BH': 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}', // Bahrain
2860
- 'BI': 'BI[0-9]{2}[0-9]{12}', // Burundi
2861
- 'BJ': 'BJ[0-9]{2}[A-Z]{1}[0-9]{23}', // Benin
2862
- 'BR': 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]', // Brazil
2863
- 'CH': 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}', // Switzerland
2864
- 'CI': 'CI[0-9]{2}[A-Z]{1}[0-9]{23}', // Ivory Coast
2865
- 'CM': 'CM[0-9]{2}[0-9]{23}', // Cameroon
2866
- 'CR': 'CR[0-9]{2}[0-9]{3}[0-9]{14}', // Costa Rica
2867
- 'CV': 'CV[0-9]{2}[0-9]{21}', // Cape Verde
2868
- 'CY': 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}', // Cyprus
2869
- 'CZ': 'CZ[0-9]{2}[0-9]{20}', // Czech Republic
2870
- 'DE': 'DE[0-9]{2}[0-9]{8}[0-9]{10}', // Germany
2871
- 'DK': 'DK[0-9]{2}[0-9]{14}', // Denmark
2872
- 'DO': 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}', // Dominican Republic
2873
- 'DZ': 'DZ[0-9]{2}[0-9]{20}', // Algeria
2874
- 'EE': 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}', // Estonia
2875
- 'ES': 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}', // Spain
2876
- 'FI': 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}', // Finland
2877
- 'FO': 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', // Faroe Islands
2878
- 'FR': 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', // France
2879
- 'GB': 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', // United Kingdom
2880
- 'GE': 'GE[0-9]{2}[A-Z]{2}[0-9]{16}', // Georgia
2881
- 'GI': 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}', // Gibraltar
2882
- 'GL': 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', // Greenland
2883
- 'GR': 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}', // Greece
2884
- 'GT': 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}', // Guatemala
2885
- 'HR': 'HR[0-9]{2}[0-9]{7}[0-9]{10}', // Croatia
2886
- 'HU': 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}', // Hungary
2887
- 'IE': 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', // Ireland
2888
- 'IL': 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}', // Israel
2889
- 'IR': 'IR[0-9]{2}[0-9]{22}', // Iran
2890
- 'IS': 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}', // Iceland
2891
- 'IT': 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', // Italy
2892
- 'JO': 'JO[0-9]{2}[A-Z]{4}[0-9]{4}[0]{8}[A-Z0-9]{10}', // Jordan
2893
- 'KW': 'KW[0-9]{2}[A-Z]{4}[0-9]{22}', // Kuwait
2894
- 'KZ': 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}', // Kazakhstan
2895
- 'LB': 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}', // Lebanon
2896
- 'LI': 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}', // Liechtenstein
2897
- 'LT': 'LT[0-9]{2}[0-9]{5}[0-9]{11}', // Lithuania
2898
- 'LU': 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}', // Luxembourg
2899
- 'LV': 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}', // Latvia
2900
- 'MC': 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', // Monaco
2901
- 'MD': 'MD[0-9]{2}[A-Z0-9]{20}', // Moldova
2902
- 'ME': 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Montenegro
2903
- 'MG': 'MG[0-9]{2}[0-9]{23}', // Madagascar
2904
- 'MK': 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}', // Macedonia
2905
- 'ML': 'ML[0-9]{2}[A-Z]{1}[0-9]{23}', // Mali
2906
- 'MR': 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}', // Mauritania
2907
- 'MT': 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}', // Malta
2908
- 'MU': 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}',// Mauritius
2909
- 'MZ': 'MZ[0-9]{2}[0-9]{21}', // Mozambique
2910
- 'NL': 'NL[0-9]{2}[A-Z]{4}[0-9]{10}', // Netherlands
2911
- 'NO': 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}', // Norway
2912
- 'PK': 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', // Pakistan
2913
- 'PL': 'PL[0-9]{2}[0-9]{8}[0-9]{16}', // Poland
2914
- 'PS': 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', // Palestinian
2915
- 'PT': 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}', // Portugal
2916
- 'QA': 'QA[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', // Qatar
2917
- 'RO': 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', // Romania
2918
- 'RS': 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Serbia
2919
- 'SA': 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}', // Saudi Arabia
2920
- 'SE': 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}', // Sweden
2921
- 'SI': 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}', // Slovenia
2922
- 'SK': 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}', // Slovakia
2923
- 'SM': 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', // San Marino
2924
- 'SN': 'SN[0-9]{2}[A-Z]{1}[0-9]{23}', // Senegal
2925
- 'TN': 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Tunisia
2926
- 'TR': 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}', // Turkey
2927
- 'VG': 'VG[0-9]{2}[A-Z]{4}[0-9]{16}' // Virgin Islands, British
2932
+ AD: 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}', // Andorra
2933
+ AE: 'AE[0-9]{2}[0-9]{3}[0-9]{16}', // United Arab Emirates
2934
+ AL: 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}', // Albania
2935
+ AO: 'AO[0-9]{2}[0-9]{21}', // Angola
2936
+ AT: 'AT[0-9]{2}[0-9]{5}[0-9]{11}', // Austria
2937
+ AZ: 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}', // Azerbaijan
2938
+ BA: 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}', // Bosnia and Herzegovina
2939
+ BE: 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}', // Belgium
2940
+ BF: 'BF[0-9]{2}[0-9]{23}', // Burkina Faso
2941
+ BG: 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}', // Bulgaria
2942
+ BH: 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}', // Bahrain
2943
+ BI: 'BI[0-9]{2}[0-9]{12}', // Burundi
2944
+ BJ: 'BJ[0-9]{2}[A-Z]{1}[0-9]{23}', // Benin
2945
+ BR: 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]', // Brazil
2946
+ CH: 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}', // Switzerland
2947
+ CI: 'CI[0-9]{2}[A-Z]{1}[0-9]{23}', // Ivory Coast
2948
+ CM: 'CM[0-9]{2}[0-9]{23}', // Cameroon
2949
+ CR: 'CR[0-9]{2}[0-9]{3}[0-9]{14}', // Costa Rica
2950
+ CV: 'CV[0-9]{2}[0-9]{21}', // Cape Verde
2951
+ CY: 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}', // Cyprus
2952
+ CZ: 'CZ[0-9]{2}[0-9]{20}', // Czech Republic
2953
+ DE: 'DE[0-9]{2}[0-9]{8}[0-9]{10}', // Germany
2954
+ DK: 'DK[0-9]{2}[0-9]{14}', // Denmark
2955
+ DO: 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}', // Dominican Republic
2956
+ DZ: 'DZ[0-9]{2}[0-9]{20}', // Algeria
2957
+ EE: 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}', // Estonia
2958
+ ES: 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}', // Spain
2959
+ FI: 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}', // Finland
2960
+ FO: 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', // Faroe Islands
2961
+ FR: 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', // France
2962
+ GB: 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', // United Kingdom
2963
+ GE: 'GE[0-9]{2}[A-Z]{2}[0-9]{16}', // Georgia
2964
+ GI: 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}', // Gibraltar
2965
+ GL: 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', // Greenland
2966
+ GR: 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}', // Greece
2967
+ GT: 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}', // Guatemala
2968
+ HR: 'HR[0-9]{2}[0-9]{7}[0-9]{10}', // Croatia
2969
+ HU: 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}', // Hungary
2970
+ IE: 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', // Ireland
2971
+ IL: 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}', // Israel
2972
+ IR: 'IR[0-9]{2}[0-9]{22}', // Iran
2973
+ IS: 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}', // Iceland
2974
+ IT: 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', // Italy
2975
+ JO: 'JO[0-9]{2}[A-Z]{4}[0-9]{4}[0]{8}[A-Z0-9]{10}', // Jordan
2976
+ KW: 'KW[0-9]{2}[A-Z]{4}[0-9]{22}', // Kuwait
2977
+ KZ: 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}', // Kazakhstan
2978
+ LB: 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}', // Lebanon
2979
+ LI: 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}', // Liechtenstein
2980
+ LT: 'LT[0-9]{2}[0-9]{5}[0-9]{11}', // Lithuania
2981
+ LU: 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}', // Luxembourg
2982
+ LV: 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}', // Latvia
2983
+ MC: 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', // Monaco
2984
+ MD: 'MD[0-9]{2}[A-Z0-9]{20}', // Moldova
2985
+ ME: 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Montenegro
2986
+ MG: 'MG[0-9]{2}[0-9]{23}', // Madagascar
2987
+ MK: 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}', // Macedonia
2988
+ ML: 'ML[0-9]{2}[A-Z]{1}[0-9]{23}', // Mali
2989
+ MR: 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}', // Mauritania
2990
+ MT: 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}', // Malta
2991
+ MU: 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}', // Mauritius
2992
+ MZ: 'MZ[0-9]{2}[0-9]{21}', // Mozambique
2993
+ NL: 'NL[0-9]{2}[A-Z]{4}[0-9]{10}', // Netherlands
2994
+ NO: 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}', // Norway
2995
+ PK: 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', // Pakistan
2996
+ PL: 'PL[0-9]{2}[0-9]{8}[0-9]{16}', // Poland
2997
+ PS: 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', // Palestinian
2998
+ PT: 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}', // Portugal
2999
+ QA: 'QA[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', // Qatar
3000
+ RO: 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', // Romania
3001
+ RS: 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Serbia
3002
+ SA: 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}', // Saudi Arabia
3003
+ SE: 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}', // Sweden
3004
+ SI: 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}', // Slovenia
3005
+ SK: 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}', // Slovakia
3006
+ SM: 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', // San Marino
3007
+ SN: 'SN[0-9]{2}[A-Z]{1}[0-9]{23}', // Senegal
3008
+ TN: 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', // Tunisia
3009
+ TR: 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}', // Turkey
3010
+ VG: 'VG[0-9]{2}[A-Z]{4}[0-9]{16}' // Virgin Islands, British
2928
3011
  },
2929
3012
 
2930
3013
  /**
@@ -3837,7 +3920,7 @@
3837
3920
  }
3838
3921
 
3839
3922
  var compareWith = validator.getFieldElements(options.field);
3840
- if (compareWith === null) {
3923
+ if (compareWith === null || compareWith.length === 0) {
3841
3924
  return true;
3842
3925
  }
3843
3926
 
@@ -3894,6 +3977,51 @@
3894
3977
  }
3895
3978
  };
3896
3979
  }(window.jQuery));
3980
+ ;(function($) {
3981
+ $.fn.bootstrapValidator.i18n.imo = $.extend($.fn.bootstrapValidator.i18n.imo || {}, {
3982
+ 'default': 'Please enter a valid IMO number'
3983
+ });
3984
+
3985
+ $.fn.bootstrapValidator.validators.imo = {
3986
+ /**
3987
+ * Validate IMO (International Maritime Organization)
3988
+ * Examples:
3989
+ * - Valid: IMO 8814275, IMO 9176187
3990
+ * - Invalid: IMO 8814274
3991
+ *
3992
+ * @see http://en.wikipedia.org/wiki/IMO_Number
3993
+ * @param {BootstrapValidator} validator The validator plugin instance
3994
+ * @param {jQuery} $field Field element
3995
+ * @param {Object} options Can consist of the following keys:
3996
+ * - message: The invalid message
3997
+ * @returns {Boolean}
3998
+ */
3999
+ validate: function(validator, $field, options) {
4000
+ var value = $field.val();
4001
+ if (value === '') {
4002
+ return true;
4003
+ }
4004
+
4005
+ if (!/^IMO \d{7}$/i.test(value)) {
4006
+ return false;
4007
+ }
4008
+
4009
+ // Grab just the digits
4010
+ var sum = 0,
4011
+ digits = value.replace(/^.*(\d{7})$/, '$1');
4012
+
4013
+ // Go over each char, multiplying by the inverse of it's position
4014
+ // IMO 9176187
4015
+ // (9 * 7) + (1 * 6) + (7 * 5) + (6 * 4) + (1 * 3) + (8 * 2) = 147
4016
+ // Take the last digit of that, that's the check digit (7)
4017
+ for (var i = 6; i >= 1; i--) {
4018
+ sum += (digits.slice((6 - i), -i) * (i + 1));
4019
+ }
4020
+
4021
+ return sum % 10 === parseInt(digits.charAt(6), 10);
4022
+ }
4023
+ };
4024
+ }(window.jQuery));
3897
4025
  ;(function($) {
3898
4026
  $.fn.bootstrapValidator.i18n.integer = $.extend($.fn.bootstrapValidator.i18n.integer || {}, {
3899
4027
  'default': 'Please enter a valid number'
@@ -3914,6 +4042,10 @@
3914
4042
  * @returns {Boolean}
3915
4043
  */
3916
4044
  validate: function(validator, $field, options) {
4045
+ if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
4046
+ return false;
4047
+ }
4048
+
3917
4049
  var value = $field.val();
3918
4050
  if (value === '') {
3919
4051
  return true;
@@ -3954,23 +4086,37 @@
3954
4086
  }
3955
4087
  options = $.extend({}, { ipv4: true, ipv6: true }, options);
3956
4088
 
3957
- if (options.ipv4) {
3958
- return {
3959
- valid: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(value),
3960
- message: options.message || $.fn.bootstrapValidator.i18n.ip.ipv4
3961
- };
3962
- } else if (options.ipv6) {
3963
- return {
3964
- valid: /^\s*((([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}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(value),
3965
- message: options.message || $.fn.bootstrapValidator.i18n.ip.ipv6
3966
- };
4089
+ var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
4090
+ ipv6Regex = /^\s*((([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}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/,
4091
+ valid = false,
4092
+ message;
4093
+
4094
+ switch (true) {
4095
+ case (options.ipv4 && !options.ipv6):
4096
+ valid = ipv4Regex.test(value);
4097
+ message = options.message || $.fn.bootstrapValidator.i18n.ip.ipv4;
4098
+ break;
4099
+
4100
+ case (!options.ipv4 && options.ipv6):
4101
+ valid = ipv6Regex.test(value);
4102
+ message = options.message || $.fn.bootstrapValidator.i18n.ip.ipv6;
4103
+ break;
4104
+
4105
+ case (options.ipv4 && options.ipv6):
4106
+ /* falls through */
4107
+ default:
4108
+ valid = ipv4Regex.test(value) && ipv6Regex.test(value);
4109
+ message = options.message || $.fn.bootstrapValidator.i18n.ip['default'];
4110
+ break;
3967
4111
  }
3968
4112
 
3969
- return false;
4113
+ return {
4114
+ valid: valid,
4115
+ message: message
4116
+ };
3970
4117
  }
3971
4118
  };
3972
- }(window.jQuery));
3973
- ;(function($) {
4119
+ }(window.jQuery));;(function($) {
3974
4120
  $.fn.bootstrapValidator.i18n.isbn = $.extend($.fn.bootstrapValidator.i18n.isbn || {}, {
3975
4121
  'default': 'Please enter a valid ISBN number'
3976
4122
  });
@@ -4234,8 +4380,9 @@
4234
4380
  },
4235
4381
 
4236
4382
  enableByHtml5: function($field) {
4237
- var max = $field.attr('max');
4238
- if (max) {
4383
+ var type = $field.attr('type'),
4384
+ max = $field.attr('max');
4385
+ if (max && type !== 'date') {
4239
4386
  return {
4240
4387
  value: max
4241
4388
  };
@@ -4265,9 +4412,11 @@
4265
4412
  if (value === '') {
4266
4413
  return true;
4267
4414
  }
4415
+ if (!$.isNumeric(value)) {
4416
+ return false;
4417
+ }
4268
4418
 
4269
4419
  var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value);
4270
-
4271
4420
  value = parseFloat(value);
4272
4421
  return (options.inclusive === true || options.inclusive === undefined)
4273
4422
  ? {
@@ -4306,6 +4455,89 @@
4306
4455
  }
4307
4456
  };
4308
4457
  }(window.jQuery));
4458
+ ;(function($) {
4459
+ $.fn.bootstrapValidator.i18n.meid = $.extend($.fn.bootstrapValidator.i18n.meid || {}, {
4460
+ 'default': 'Please enter a valid MEID number'
4461
+ });
4462
+
4463
+ $.fn.bootstrapValidator.validators.meid = {
4464
+ /**
4465
+ * Validate MEID (Mobile Equipment Identifier)
4466
+ * Examples:
4467
+ * - Valid: 293608736500703710, 29360-87365-0070-3710, AF0123450ABCDE, AF-012345-0ABCDE
4468
+ * - Invalid: 2936087365007037101
4469
+ *
4470
+ * @see http://en.wikipedia.org/wiki/Mobile_equipment_identifier
4471
+ * @param {BootstrapValidator} validator The validator plugin instance
4472
+ * @param {jQuery} $field Field element
4473
+ * @param {Object} options Can consist of the following keys:
4474
+ * - message: The invalid message
4475
+ * @returns {Boolean}
4476
+ */
4477
+ validate: function(validator, $field, options) {
4478
+ var value = $field.val();
4479
+ if (value === '') {
4480
+ return true;
4481
+ }
4482
+
4483
+ switch (true) {
4484
+ // 14 digit hex representation (no check digit)
4485
+ case /^[0-9A-F]{15}$/i.test(value):
4486
+ // 14 digit hex representation + dashes or spaces (no check digit)
4487
+ case /^[0-9A-F]{2}[- ][0-9A-F]{6}[- ][0-9A-F]{6}[- ][0-9A-F]$/i.test(value):
4488
+ // 18 digit decimal representation (no check digit)
4489
+ case /^\d{19}$/.test(value):
4490
+ // 18 digit decimal representation + dashes or spaces (no check digit)
4491
+ case /^\d{5}[- ]\d{5}[- ]\d{4}[- ]\d{4}[- ]\d$/.test(value):
4492
+ // Grab the check digit
4493
+ var cd = value.charAt(value.length - 1);
4494
+
4495
+ // Strip any non-hex chars
4496
+ value = value.replace(/[- ]/g, '');
4497
+
4498
+ // If it's all digits, luhn base 10 is used
4499
+ if (value.match(/^\d*$/i)) {
4500
+ return $.fn.bootstrapValidator.helpers.luhn(value);
4501
+ }
4502
+
4503
+ // Strip the check digit
4504
+ value = value.slice(0, -1);
4505
+
4506
+ // Get every other char, and double it
4507
+ var cdCalc = '';
4508
+ for (var i = 1; i <= 13; i += 2) {
4509
+ cdCalc += (parseInt(value.charAt(i), 16) * 2).toString(16);
4510
+ }
4511
+
4512
+ // Get the sum of each char in the string
4513
+ var sum = 0;
4514
+ for (i = 0; i < cdCalc.length; i++) {
4515
+ sum += parseInt(cdCalc.charAt(i), 16);
4516
+ }
4517
+
4518
+ // If the last digit of the calc is 0, the check digit is 0
4519
+ return (sum % 10 === 0)
4520
+ ? (cd === '0')
4521
+ // Subtract it from the next highest 10s number (64 goes to 70) and subtract the sum
4522
+ // Double it and turn it into a hex char
4523
+ : (cd === ((Math.floor((sum + 10) / 10) * 10 - sum) * 2).toString(16));
4524
+
4525
+ // 14 digit hex representation (no check digit)
4526
+ case /^[0-9A-F]{14}$/i.test(value):
4527
+ // 14 digit hex representation + dashes or spaces (no check digit)
4528
+ case /^[0-9A-F]{2}[- ][0-9A-F]{6}[- ][0-9A-F]{6}$/i.test(value):
4529
+ // 18 digit decimal representation (no check digit)
4530
+ case /^\d{18}$/.test(value):
4531
+ // 18 digit decimal representation + dashes or spaces (no check digit)
4532
+ case /^\d{5}[- ]\d{5}[- ]\d{4}[- ]\d{4}$/.test(value):
4533
+ return true;
4534
+
4535
+ default:
4536
+ return false;
4537
+ }
4538
+ }
4539
+ };
4540
+ }(window.jQuery));
4309
4541
  ;(function($) {
4310
4542
  $.fn.bootstrapValidator.i18n.notEmpty = $.extend($.fn.bootstrapValidator.i18n.notEmpty || {}, {
4311
4543
  'default': 'Please enter a value'
@@ -4364,6 +4596,10 @@
4364
4596
  * @returns {Boolean}
4365
4597
  */
4366
4598
  validate: function(validator, $field, options) {
4599
+ if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
4600
+ return false;
4601
+ }
4602
+
4367
4603
  var value = $field.val();
4368
4604
  if (value === '') {
4369
4605
  return true;
@@ -4383,7 +4619,12 @@
4383
4619
  countryNotSupported: 'The country code %s is not supported',
4384
4620
  country: 'Please enter a valid phone number in %s',
4385
4621
  countries: {
4622
+ BR: 'Brazil',
4623
+ ES: 'Spain',
4624
+ FR: 'France',
4386
4625
  GB: 'United Kingdom',
4626
+ MA: 'Morocco',
4627
+ PK: 'Pakistan',
4387
4628
  US: 'USA'
4388
4629
  }
4389
4630
  });
@@ -4395,7 +4636,7 @@
4395
4636
  },
4396
4637
 
4397
4638
  // The supported countries
4398
- COUNTRY_CODES: ['GB', 'US'],
4639
+ COUNTRY_CODES: ['BR', 'ES', 'FR', 'GB', 'MA', 'PK', 'US'],
4399
4640
 
4400
4641
  /**
4401
4642
  * Return true if the input value contains a valid phone number for the country
@@ -4411,7 +4652,6 @@
4411
4652
  * - Name of callback function that returns the country code
4412
4653
  * - A callback function that returns the country code
4413
4654
  *
4414
- * Currently it only supports United State (US) or United Kingdom (GB) countries
4415
4655
  * @returns {Boolean|Object}
4416
4656
  */
4417
4657
  validate: function(validator, $field, options) {
@@ -4435,6 +4675,24 @@
4435
4675
 
4436
4676
  var isValid = true;
4437
4677
  switch (country.toUpperCase()) {
4678
+ case 'BR':
4679
+ // Test: http://regexr.com/399m1
4680
+ value = $.trim(value);
4681
+ isValid = (/^(([\d]{4}[-.\s]{1}[\d]{2,3}[-.\s]{1}[\d]{2}[-.\s]{1}[\d]{2})|([\d]{4}[-.\s]{1}[\d]{3}[-.\s]{1}[\d]{4})|((\(?\+?[0-9]{2}\)?\s?)?(\(?\d{2}\)?\s?)?\d{4,5}[-.\s]?\d{4}))$/).test(value);
4682
+ break;
4683
+
4684
+ case 'ES':
4685
+ // http://regex101.com/r/rB9mA9/1
4686
+ value = $.trim(value);
4687
+ isValid = (/^(?:(?:(?:\+|00)34\D?))?(?:9|6)(?:\d\D?){8}$/).test(value);
4688
+ break;
4689
+
4690
+ case 'FR':
4691
+ // http://regexr.com/39a2p
4692
+ value = $.trim(value);
4693
+ isValid = (/^(?:(?:(?:\+|00)33[ ]?(?:\(0\)[ ]?)?)|0){1}[1-9]{1}([ .-]?)(?:\d{2}\1?){3}\d{2}$/).test(value);
4694
+ break;
4695
+
4438
4696
  case 'GB':
4439
4697
  // http://aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers#Match_GB_telephone_number_in_any_format
4440
4698
  // Test: http://regexr.com/38uhv
@@ -4442,6 +4700,19 @@
4442
4700
  isValid = (/^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\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}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$/).test(value);
4443
4701
  break;
4444
4702
 
4703
+ case 'MA':
4704
+ // http://en.wikipedia.org/wiki/Telephone_numbers_in_Morocco
4705
+ // Test: http://regexr.com/399n8
4706
+ value = $.trim(value);
4707
+ isValid = (/^(?:(?:(?:\+|00)212[\s]?(?:[\s]?\(0\)[\s]?)?)|0){1}(?:5[\s.-]?[2-3]|6[\s.-]?[13-9]){1}[0-9]{1}(?:[\s.-]?\d{2}){3}$/).test(value);
4708
+ break;
4709
+
4710
+ case 'PK':
4711
+ // http://regex101.com/r/yH8aV9/2
4712
+ value = $.trim(value);
4713
+ isValid = (/^0?3[0-9]{2}[0-9]{7}$/).test(value);
4714
+ break;
4715
+
4445
4716
  case 'US':
4446
4717
  /* falls through */
4447
4718
  default:
@@ -4511,8 +4782,9 @@
4511
4782
  $.fn.bootstrapValidator.validators.remote = {
4512
4783
  html5Attributes: {
4513
4784
  message: 'message',
4514
- url: 'url',
4515
- name: 'name'
4785
+ name: 'name',
4786
+ type: 'type',
4787
+ url: 'url'
4516
4788
  },
4517
4789
 
4518
4790
  /**
@@ -4529,6 +4801,7 @@
4529
4801
  * }
4530
4802
  * - name {String} [optional]: Override the field name for the request.
4531
4803
  * - message: The invalid message
4804
+ * - headers: Additional headers
4532
4805
  * @returns {Boolean|Deferred}
4533
4806
  */
4534
4807
  validate: function(validator, $field, options) {
@@ -4537,10 +4810,11 @@
4537
4810
  return true;
4538
4811
  }
4539
4812
 
4540
- var name = $field.attr('data-bv-field'),
4541
- data = options.data || {},
4542
- url = options.url,
4543
- type = options.type || 'POST';
4813
+ var name = $field.attr('data-bv-field'),
4814
+ data = options.data || {},
4815
+ url = options.url,
4816
+ type = options.type || 'POST',
4817
+ headers = options.headers || {};
4544
4818
 
4545
4819
  // Support dynamic data
4546
4820
  if ('function' === typeof data) {
@@ -4557,6 +4831,7 @@
4557
4831
  var dfd = new $.Deferred();
4558
4832
  var xhr = $.ajax({
4559
4833
  type: type,
4834
+ headers: headers,
4560
4835
  url: url,
4561
4836
  dataType: 'json',
4562
4837
  data: data
@@ -4946,7 +5221,7 @@
4946
5221
  // Notes on possible differences from a standard/generic validation:
4947
5222
  //
4948
5223
  // - utf-8 char class take in consideration the full Unicode range
4949
- // - TLDs have been made mandatory so single names like "localhost" fails
5224
+ // - TLDs are mandatory unless `allowLocal` is true
4950
5225
  // - protocols have been restricted to ftp, http and https only as requested
4951
5226
  //
4952
5227
  // Changes:
@@ -4956,6 +5231,7 @@
4956
5231
  // (since they are broadcast/network addresses)
4957
5232
  //
4958
5233
  // - Added exclusion of private, reserved and/or local networks ranges
5234
+ // unless `allowLocal` is true
4959
5235
  //
4960
5236
  var allowLocal = options.allowLocal === true || options.allowLocal === 'true',
4961
5237
  urlExp = new RegExp(
@@ -4987,6 +5263,8 @@
4987
5263
  "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*" +
4988
5264
  // TLD identifier
4989
5265
  "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
5266
+ // Allow intranet sites (no TLD) if `allowLocal` is true
5267
+ (allowLocal ? '?' : '') +
4990
5268
  ")" +
4991
5269
  // port number
4992
5270
  "(?::\\d{2,5})?" +
@@ -5054,6 +5332,7 @@
5054
5332
  AT: 'Austrian',
5055
5333
  BE: 'Belgian',
5056
5334
  BG: 'Bulgarian',
5335
+ BR: 'Brazilian',
5057
5336
  CH: 'Swiss',
5058
5337
  CY: 'Cypriot',
5059
5338
  CZ: 'Czech',
@@ -5069,6 +5348,7 @@
5069
5348
  HU: 'Hungarian',
5070
5349
  HR: 'Croatian',
5071
5350
  IE: 'Irish',
5351
+ IS: 'Iceland',
5072
5352
  IT: 'Italian',
5073
5353
  LT: 'Lithuanian',
5074
5354
  LU: 'Luxembourg',
@@ -5083,7 +5363,8 @@
5083
5363
  RS: 'Serbian',
5084
5364
  SE: 'Swedish',
5085
5365
  SI: 'Slovenian',
5086
- SK: 'Slovak'
5366
+ SK: 'Slovak',
5367
+ ZA: 'South African'
5087
5368
  }
5088
5369
  });
5089
5370
 
@@ -5095,8 +5376,8 @@
5095
5376
 
5096
5377
  // Supported country codes
5097
5378
  COUNTRY_CODES: [
5098
- 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'EL', 'HU', 'IE', 'IT',
5099
- 'LV', 'LT', 'LU', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'RS', 'SK', 'SI', 'ES', 'SE', 'CH', 'GB'
5379
+ 'AT', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI', 'FR', 'GB', 'GR', 'HR', 'HU',
5380
+ 'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'RS', 'SE', 'SK', 'SI', 'ZA'
5100
5381
  ],
5101
5382
 
5102
5383
  /**
@@ -5301,6 +5582,64 @@
5301
5582
 
5302
5583
  return false;
5303
5584
  },
5585
+
5586
+ /**
5587
+ * Validate Brazilian VAT number (CNPJ)
5588
+ *
5589
+ * @param {String} value VAT number
5590
+ * @returns {Boolean}
5591
+ */
5592
+ _br: function(value) {
5593
+ if (value === '') {
5594
+ return true;
5595
+ }
5596
+ var cnpj = value.replace(/[^\d]+/g, '');
5597
+ if (cnpj === '' || cnpj.length !== 14) {
5598
+ return false;
5599
+ }
5600
+
5601
+ // Remove invalids CNPJs
5602
+ if (cnpj === '00000000000000' || cnpj === '11111111111111' || cnpj === '22222222222222' ||
5603
+ cnpj === '33333333333333' || cnpj === '44444444444444' || cnpj === '55555555555555' ||
5604
+ cnpj === '66666666666666' || cnpj === '77777777777777' || cnpj === '88888888888888' ||
5605
+ cnpj === '99999999999999')
5606
+ {
5607
+ return false;
5608
+ }
5609
+
5610
+ // Validate verification digits
5611
+ var length = cnpj.length - 2,
5612
+ numbers = cnpj.substring(0, length),
5613
+ digits = cnpj.substring(length),
5614
+ sum = 0,
5615
+ pos = length - 7;
5616
+
5617
+ for (var i = length; i >= 1; i--) {
5618
+ sum += parseInt(numbers.charAt(length - i), 10) * pos--;
5619
+ if (pos < 2) {
5620
+ pos = 9;
5621
+ }
5622
+ }
5623
+
5624
+ var result = sum % 11 < 2 ? 0 : 11 - sum % 11;
5625
+ if (result !== parseInt(digits.charAt(0), 10)) {
5626
+ return false;
5627
+ }
5628
+
5629
+ length = length + 1;
5630
+ numbers = cnpj.substring(0, length);
5631
+ sum = 0;
5632
+ pos = length - 7;
5633
+ for (i = length; i >= 1; i--) {
5634
+ sum += parseInt(numbers.charAt(length - i), 10) * pos--;
5635
+ if (pos < 2) {
5636
+ pos = 9;
5637
+ }
5638
+ }
5639
+
5640
+ result = sum % 11 < 2 ? 0 : 11 - sum % 11;
5641
+ return (result === parseInt(digits.charAt(1), 10));
5642
+ },
5304
5643
 
5305
5644
  /**
5306
5645
  * Validate Swiss VAT number
@@ -5641,7 +5980,7 @@
5641
5980
 
5642
5981
  value = value.substr(2);
5643
5982
 
5644
- if (!$.fn.bootstrapValidator.helpers.luhn(value.substr(2))) {
5983
+ if (!$.fn.bootstrapValidator.helpers.luhn(value.substr(2))) {
5645
5984
  return false;
5646
5985
  }
5647
5986
 
@@ -5834,6 +6173,19 @@
5834
6173
  return true;
5835
6174
  },
5836
6175
 
6176
+ /**
6177
+ * Validate Icelandic VAT (VSK) number
6178
+ * Examples:
6179
+ * - Valid: 12345, 123456
6180
+ * - Invalid: 1234567
6181
+ *
6182
+ * @params {String} value VAT number
6183
+ * @returns {Boolean}
6184
+ */
6185
+ _is: function(value) {
6186
+ return /^IS\d{5,6}$/.test(value);
6187
+ },
6188
+
5837
6189
  /**
5838
6190
  * Validate Italian VAT number, which consists of 11 digits.
5839
6191
  * - First 7 digits are a company identifier
@@ -6262,6 +6614,19 @@
6262
6614
  }
6263
6615
 
6264
6616
  return (parseInt(value.substr(2), 10) % 11 === 0);
6617
+ },
6618
+
6619
+ /**
6620
+ * Validate South African VAT number
6621
+ * Examples:
6622
+ * - Valid: 4012345678
6623
+ * - Invalid: 40123456789, 3012345678
6624
+ *
6625
+ * @params {String} value VAT number
6626
+ * @returns {Boolean}
6627
+ */
6628
+ _za: function(value) {
6629
+ return /^ZA4\d{9}$/.test(value);
6265
6630
  }
6266
6631
  };
6267
6632
  }(window.jQuery));
@@ -6320,14 +6685,16 @@
6320
6685
  countryNotSupported: 'The country code %s is not supported',
6321
6686
  country: 'Please enter a valid %s',
6322
6687
  countries: {
6323
- 'CA': 'Canadian postal code',
6324
- 'DK': 'Danish postal code',
6325
- 'GB': 'United Kingdom postal code',
6326
- 'IT': 'Italian postal code',
6327
- 'NL': 'Dutch postal code',
6328
- 'SE': 'Swiss postal code',
6329
- 'SG': 'Singapore postal code',
6330
- 'US': 'US zip code'
6688
+ BR: 'Brazilian postal code',
6689
+ CA: 'Canadian postal code',
6690
+ DK: 'Danish postal code',
6691
+ GB: 'United Kingdom postal code',
6692
+ IT: 'Italian postal code',
6693
+ MA: 'Moroccan postal code',
6694
+ NL: 'Dutch postal code',
6695
+ SE: 'Swiss postal code',
6696
+ SG: 'Singapore postal code',
6697
+ US: 'US zip code'
6331
6698
  }
6332
6699
  });
6333
6700
 
@@ -6337,7 +6704,7 @@
6337
6704
  country: 'country'
6338
6705
  },
6339
6706
 
6340
- COUNTRY_CODES: ['CA', 'DK', 'GB', 'IT', 'NL', 'SE', 'SG', 'US'],
6707
+ COUNTRY_CODES: ['BR', 'CA', 'DK', 'GB', 'IT', 'MA', 'NL', 'SE', 'SG', 'US'],
6341
6708
 
6342
6709
  /**
6343
6710
  * Return true if and only if the input value is a valid country zip code
@@ -6350,16 +6717,6 @@
6350
6717
  *
6351
6718
  * The country can be defined by:
6352
6719
  * - An ISO 3166 country code
6353
- * Currently it supports the following countries:
6354
- * - US (United States)
6355
- * - CA (Canada)
6356
- * - DK (Denmark)
6357
- * - GB (United Kingdom)
6358
- * - IT (Italy)
6359
- * - NL (Netherlands)
6360
- * - SE (Sweden)
6361
- * - SG (Singapore)
6362
- *
6363
6720
  * - Name of field which its value defines the country code
6364
6721
  * - Name of callback function that returns the country code
6365
6722
  * - A callback function that returns the country code
@@ -6391,6 +6748,10 @@
6391
6748
  var isValid = false;
6392
6749
  country = country.toUpperCase();
6393
6750
  switch (country) {
6751
+ case 'BR':
6752
+ isValid = /^(\d{2})([\.]?)(\d{3})([\-]?)(\d{3})$/.test(value);
6753
+ break;
6754
+
6394
6755
  case 'CA':
6395
6756
  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);
6396
6757
  break;
@@ -6408,6 +6769,11 @@
6408
6769
  isValid = /^(I-|IT-)?\d{5}$/i.test(value);
6409
6770
  break;
6410
6771
 
6772
+ // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Morocco
6773
+ case 'MA':
6774
+ isValid = /^[1-9][0-9]{4}$/i.test(value);
6775
+ break;
6776
+
6411
6777
  // http://en.wikipedia.org/wiki/Postal_codes_in_the_Netherlands
6412
6778
  case 'NL':
6413
6779
  isValid = /^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i.test(value);
@@ -6419,8 +6785,8 @@
6419
6785
 
6420
6786
  case 'SG':
6421
6787
  isValid = /^([0][1-9]|[1-6][0-9]|[7]([0-3]|[5-9])|[8][0-2])(\d{4})$/i.test(value);
6422
- break;
6423
-
6788
+ break;
6789
+
6424
6790
  case 'US':
6425
6791
  /* falls through */
6426
6792
  default: