vendor/assets/javascripts/bootstrapValidator.js in bootstrap-validator-rails-0.5.1 vs vendor/assets/javascripts/bootstrapValidator.js in bootstrap-validator-rails-0.5.2
- old
+ new
@@ -1,14 +1,18 @@
/*!
* BootstrapValidator (http://bootstrapvalidator.com)
* The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
*
- * @version v0.5.1, built on 2014-08-22 4:55:09 PM
+ * @version v0.5.2, built on 2014-09-25 4:01:07 PM
* @author https://twitter.com/nghuuphuoc
* @copyright (c) 2013 - 2014 Nguyen Huu Phuoc
* @license MIT
*/
+if (typeof jQuery === 'undefined') {
+ throw new Error('BootstrapValidator\'s JavaScript requires jQuery');
+}
+
(function($) {
var BootstrapValidator = function(form, options) {
this.$form = $(form);
this.options = $.extend({}, $.fn.bootstrapValidator.DEFAULT_OPTIONS, options);
@@ -52,26 +56,11 @@
* Init form
*/
_init: function() {
var that = this,
options = {
- excluded: this.$form.attr('data-bv-excluded'),
- trigger: this.$form.attr('data-bv-trigger'),
- message: this.$form.attr('data-bv-message'),
container: this.$form.attr('data-bv-container'),
- group: this.$form.attr('data-bv-group'),
- submitButtons: this.$form.attr('data-bv-submitbuttons'),
- threshold: this.$form.attr('data-bv-threshold'),
- live: this.$form.attr('data-bv-live'),
- onSuccess: this.$form.attr('data-bv-onsuccess'),
- onError: this.$form.attr('data-bv-onerror'),
- fields: {},
- feedbackIcons: {
- valid: this.$form.attr('data-bv-feedbackicons-valid'),
- invalid: this.$form.attr('data-bv-feedbackicons-invalid'),
- validating: this.$form.attr('data-bv-feedbackicons-validating')
- },
events: {
formInit: this.$form.attr('data-bv-events-form-init'),
formError: this.$form.attr('data-bv-events-form-error'),
formSuccess: this.$form.attr('data-bv-events-form-success'),
fieldAdded: this.$form.attr('data-bv-events-field-added'),
@@ -80,11 +69,27 @@
fieldError: this.$form.attr('data-bv-events-field-error'),
fieldSuccess: this.$form.attr('data-bv-events-field-success'),
fieldStatus: this.$form.attr('data-bv-events-field-status'),
validatorError: this.$form.attr('data-bv-events-validator-error'),
validatorSuccess: this.$form.attr('data-bv-events-validator-success')
- }
+ },
+ excluded: this.$form.attr('data-bv-excluded'),
+ feedbackIcons: {
+ valid: this.$form.attr('data-bv-feedbackicons-valid'),
+ invalid: this.$form.attr('data-bv-feedbackicons-invalid'),
+ validating: this.$form.attr('data-bv-feedbackicons-validating')
+ },
+ group: this.$form.attr('data-bv-group'),
+ live: this.$form.attr('data-bv-live'),
+ message: this.$form.attr('data-bv-message'),
+ onError: this.$form.attr('data-bv-onerror'),
+ onSuccess: this.$form.attr('data-bv-onsuccess'),
+ submitButtons: this.$form.attr('data-bv-submitbuttons'),
+ threshold: this.$form.attr('data-bv-threshold'),
+ trigger: this.$form.attr('data-bv-trigger'),
+ verbose: this.$form.attr('data-bv-verbose'),
+ fields: {}
};
this.$form
// Disable client side validation in HTML 5
.attr('novalidate', 'novalidate')
@@ -122,15 +127,21 @@
.addClass('bv-hidden-submit')
.css({ display: 'none', width: 0, height: 0 });
this.$form
.on('click.bv', '[type="submit"]', function(e) {
- // Don't perform validation when clicking on the submit button/input
- // which aren't defined by the 'submitButtons' option
- var $button = $(e.target).eq(0);
- if (that.options.submitButtons && !$button.is(that.options.submitButtons) && !$button.is(that.$hiddenButton)) {
- that.$form.off('submit.bv').submit();
+ // #746: Check if the button click handler returns false
+ if (!e.isDefaultPrevented()) {
+ var $target = $(e.target),
+ // The button might contain HTML tag
+ $button = $target.is('[type="submit"]') ? $target.eq(0) : $target.parent('[type="submit"]').eq(0);
+
+ // Don't perform validation when clicking on the submit button/input
+ // which aren't defined by the 'submitButtons' option
+ if (that.options.submitButtons && !$button.is(that.options.submitButtons) && !$button.is(that.$hiddenButton)) {
+ that.$form.off('submit.bv').submit();
+ }
}
});
for (var field in this.options.fields) {
this._initField(field);
@@ -197,21 +208,22 @@
}
}
}
var opts = {
+ container: $field.attr('data-bv-container'),
excluded: $field.attr('data-bv-excluded'),
feedbackIcons: $field.attr('data-bv-feedbackicons'),
- trigger: $field.attr('data-bv-trigger'),
- message: $field.attr('data-bv-message'),
- container: $field.attr('data-bv-container'),
group: $field.attr('data-bv-group'),
- selector: $field.attr('data-bv-selector'),
- threshold: $field.attr('data-bv-threshold'),
+ message: $field.attr('data-bv-message'),
+ onError: $field.attr('data-bv-onerror'),
onStatus: $field.attr('data-bv-onstatus'),
onSuccess: $field.attr('data-bv-onsuccess'),
- onError: $field.attr('data-bv-onerror'),
+ selector: $field.attr('data-bv-selector'),
+ threshold: $field.attr('data-bv-threshold'),
+ trigger: $field.attr('data-bv-trigger'),
+ verbose: $field.attr('data-bv-verbose'),
validators: validators
},
emptyOptions = $.isEmptyObject(opts), // Check if the field options are set using HTML attributes
emptyValidators = $.isEmptyObject(validators); // Check if the field validators are set using HTML attributes
@@ -241,19 +253,19 @@
break;
default:
break;
}
- if (this.options.fields[field] === null || this.options.fields[field].validators === null) {
+ // We don't need to validate non-existing fields
+ if (fields.length === 0) {
return;
}
- // We don't need to validate non-existing fields
- if (fields.length === 0) {
- delete this.options.fields[field];
+ if (this.options.fields[field] === null || this.options.fields[field].validators === null) {
return;
}
+
var validatorName;
for (validatorName in this.options.fields[field].validators) {
if (!$.fn.bootstrapValidator.validators[validatorName]) {
delete this.options.fields[field].validators[validatorName];
}
@@ -275,11 +287,11 @@
for (var i = 0; i < total; i++) {
var $field = fields.eq(i),
group = this.options.fields[field].group || this.options.group,
$parent = $field.parents(group),
// Allow user to indicate where the error messages are shown
- container = this.options.fields[field].container || this.options.container,
+ container = ('function' === typeof (this.options.fields[field].container || this.options.container)) ? (this.options.fields[field].container || this.options.container).call(this, $field, this) : (this.options.fields[field].container || this.options.container),
$message = (container && container !== 'tooltip' && container !== 'popover') ? $(container) : this._getMessageContainer($field, group);
if (container && container !== 'tooltip' && container !== 'popover') {
$message.addClass('has-error');
}
@@ -290,11 +302,11 @@
// Whenever the user change the field value, mark it as not validated yet
$field.off(events).on(events, function() {
that.updateStatus($(this), that.STATUS_NOT_VALIDATED);
});
-
+
// Create help block elements for showing the error messages
$field.data('bv.messages', $message);
for (validatorName in this.options.fields[field].validators) {
$field.data('bv.result.' + validatorName, this.STATUS_NOT_VALIDATED);
@@ -307,31 +319,26 @@
.attr('data-bv-result', this.STATUS_NOT_VALIDATED)
.html(this._getMessage(field, validatorName))
.appendTo($message);
}
- // Prepare the validator events
- if (this.options.fields[field].validators[validatorName].onSuccess) {
- $field.on(this.options.events.validatorSuccess, function(e, data) {
- $.fn.bootstrapValidator.helpers.call(that.options.fields[field].validators[validatorName].onSuccess, [e, data]);
- });
+ // Init the validator
+ if ('function' === typeof $.fn.bootstrapValidator.validators[validatorName].init) {
+ $.fn.bootstrapValidator.validators[validatorName].init(this, $field, this.options.fields[field].validators[validatorName]);
}
- if (this.options.fields[field].validators[validatorName].onError) {
- $field.on(this.options.events.validatorError, function(e, data) {
- $.fn.bootstrapValidator.helpers.call(that.options.fields[field].validators[validatorName].onError, [e, data]);
- });
- }
}
// Prepare the feedback icons
// Available from Bootstrap 3.1 (http://getbootstrap.com/css/#forms-control-validation)
if (this.options.fields[field].feedbackIcons !== false && this.options.fields[field].feedbackIcons !== 'false'
&& this.options.feedbackIcons
&& this.options.feedbackIcons.validating && this.options.feedbackIcons.invalid && this.options.feedbackIcons.valid
&& (!updateAll || i === total - 1))
{
- $parent.removeClass('has-success').removeClass('has-error').addClass('has-feedback');
+ // $parent.removeClass('has-success').removeClass('has-error').addClass('has-feedback');
+ // Keep error messages which are populated from back-end
+ $parent.addClass('has-feedback');
var $icon = $('<i/>')
.css('display', 'none')
.addClass('form-control-feedback')
.attr('data-bv-icon-for', field)
.insertAfter($field);
@@ -348,38 +355,84 @@
}
// The feedback icon does not render correctly if there is no label
// https://github.com/twbs/bootstrap/issues/12873
if ($parent.find('label').length === 0) {
- $icon.css('top', 0);
+ $icon.addClass('bv-no-label');
}
// Fix feedback icons in input-group
if ($parent.find('.input-group').length !== 0) {
- $icon.css({
- 'top': 0,
- 'z-index': 100
- }).insertAfter($parent.find('.input-group').eq(0));
+ $icon.addClass('bv-icon-input-group')
+ .insertAfter($parent.find('.input-group').eq(0));
}
+
+ if (container) {
+ $field
+ // Show tooltip/popover message when field gets focus
+ .off('focus.bv')
+ .on('focus.bv', function() {
+ switch (container) {
+ case 'tooltip':
+ $icon.tooltip('show');
+ break;
+ case 'popover':
+ $icon.popover('show');
+ break;
+ default:
+ break;
+ }
+ })
+ // and hide them when losing focus
+ .off('blur.bv')
+ .on('blur.bv', function() {
+ switch (container) {
+ case 'tooltip':
+ $icon.tooltip('hide');
+ break;
+ case 'popover':
+ $icon.popover('hide');
+ break;
+ default:
+ break;
+ }
+ });
+ }
}
}
// Prepare the events
- if (this.options.fields[field].onSuccess) {
- fields.on(this.options.events.fieldSuccess, function(e, data) {
- $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onSuccess, [e, data]);
+ fields
+ .on(this.options.events.fieldSuccess, function(e, data) {
+ var onSuccess = that.getOptions(data.field, null, 'onSuccess');
+ if (onSuccess) {
+ $.fn.bootstrapValidator.helpers.call(onSuccess, [e, data]);
+ }
+ })
+ .on(this.options.events.fieldError, function(e, data) {
+ var onError = that.getOptions(data.field, null, 'onError');
+ if (onError) {
+ $.fn.bootstrapValidator.helpers.call(onError, [e, data]);
+ }
+ })
+ .on(this.options.events.fieldStatus, function(e, data) {
+ var onStatus = that.getOptions(data.field, null, 'onStatus');
+ if (onStatus) {
+ $.fn.bootstrapValidator.helpers.call(onStatus, [e, data]);
+ }
+ })
+ .on(this.options.events.validatorError, function(e, data) {
+ var onError = that.getOptions(data.field, data.validator, 'onError');
+ if (onError) {
+ $.fn.bootstrapValidator.helpers.call(onError, [e, data]);
+ }
+ })
+ .on(this.options.events.validatorSuccess, function(e, data) {
+ var onSuccess = that.getOptions(data.field, data.validator, 'onSuccess');
+ if (onSuccess) {
+ $.fn.bootstrapValidator.helpers.call(onSuccess, [e, data]);
+ }
});
- }
- if (this.options.fields[field].onError) {
- fields.on(this.options.events.fieldError, function(e, data) {
- $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onError, [e, data]);
- });
- }
- if (this.options.fields[field].onStatus) {
- fields.on(this.options.events.fieldStatus, function(e, data) {
- $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onStatus, [e, data]);
- });
- }
// Set live mode
events = $.map(trigger, function(item) {
return item + '.live.bv';
}).join(' ');
@@ -622,11 +675,12 @@
numValidators = 0,
data = {
bv: this,
field: field,
element: $field,
- validator: validatorName
+ validator: validatorName,
+ result: $field.data('bv.response.' + validatorName)
};
// Trigger an event after given validator completes
if (validatorName) {
switch ($field.data('bv.result.' + validatorName)) {
@@ -692,10 +746,41 @@
return this._cacheFields[field];
},
/**
+ * Get the field options
+ *
+ * @param {String|jQuery} [field] The field name or field element. If it is not set, the method returns the form options
+ * @param {String} [validator] The name of validator. It null, the method returns form options
+ * @param {String} [option] The option name
+ * @return {String|Object}
+ */
+ getOptions: function(field, validator, option) {
+ if (!field) {
+ return this.options;
+ }
+ if ('object' === typeof field) {
+ field = field.attr('data-bv-field');
+ }
+ if (!this.options.fields[field]) {
+ return null;
+ }
+
+ var options = this.options.fields[field];
+ if (!validator) {
+ return option ? options[option] : options;
+ }
+ if (!options.validators || !options.validators[validator]) {
+ return null;
+ }
+
+ return option ? options.validators[validator][option] : options.validators[validator];
+ },
+
+
+ /**
* Disable/enable submit buttons
*
* @param {Boolean} disabled Can be true or false
* @returns {BootstrapValidator}
*/
@@ -748,71 +833,89 @@
break;
default:
break;
}
- if (this.options.fields[field] && this.options.fields[field].enabled === false) {
+ if (fields.length === 0 || (this.options.fields[field] && this.options.fields[field].enabled === false)) {
return this;
}
var that = this,
type = fields.attr('type'),
total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length,
updateAll = ('radio' === type || 'checkbox' === type),
validators = this.options.fields[field].validators,
+ verbose = this.options.fields[field].verbose === 'true' || this.options.fields[field].verbose === true || this.options.verbose === 'true' || this.options.verbose === true,
validatorName,
validateResult;
for (var i = 0; i < total; i++) {
var $field = fields.eq(i);
if (this._isExcluded($field)) {
continue;
}
+ var stop = false;
for (validatorName in validators) {
if ($field.data('bv.dfs.' + validatorName)) {
$field.data('bv.dfs.' + validatorName).reject();
}
+ if (stop) {
+ break;
+ }
// Don't validate field if it is already done
var result = $field.data('bv.result.' + validatorName);
- if (result === this.STATUS_VALID || result === this.STATUS_INVALID || validators[validatorName].enabled === false) {
+ if (result === this.STATUS_VALID || result === this.STATUS_INVALID) {
this._onFieldValidated($field, validatorName);
continue;
+ } else if (validators[validatorName].enabled === false) {
+ this.updateStatus(updateAll ? field : $field, this.STATUS_VALID, validatorName);
+ continue;
}
$field.data('bv.result.' + validatorName, this.STATUS_VALIDATING);
validateResult = $.fn.bootstrapValidator.validators[validatorName].validate(this, $field, validators[validatorName]);
// validateResult can be a $.Deferred object ...
if ('object' === typeof validateResult && validateResult.resolve) {
this.updateStatus(updateAll ? field : $field, this.STATUS_VALIDATING, validatorName);
$field.data('bv.dfs.' + validatorName, validateResult);
- validateResult.done(function($f, v, isValid, message) {
+ validateResult.done(function($f, v, response) {
// v is validator name
- $f.removeData('bv.dfs.' + v);
- if (message) {
- that.updateMessage($f, v, message);
+ $f.removeData('bv.dfs.' + v).data('bv.response.' + v, response);
+ if (response.message) {
+ that.updateMessage($f, v, response.message);
}
- that.updateStatus(updateAll ? $f.attr('data-bv-field') : $f, isValid ? that.STATUS_VALID : that.STATUS_INVALID, v);
+ that.updateStatus(updateAll ? $f.attr('data-bv-field') : $f, response.valid ? that.STATUS_VALID : that.STATUS_INVALID, v);
- if (isValid && that._submitIfValid === true) {
+ if (response.valid && that._submitIfValid === true) {
// If a remote validator returns true and the form is ready to submit, then do it
that._submit();
+ } else if (!response.valid && !verbose) {
+ stop = true;
}
});
}
// ... or object { valid: true/false, message: 'dynamic message' }
else if ('object' === typeof validateResult && validateResult.valid !== undefined && validateResult.message !== undefined) {
+ $field.data('bv.response.' + validatorName, validateResult);
this.updateMessage(updateAll ? field : $field, validatorName, validateResult.message);
this.updateStatus(updateAll ? field : $field, validateResult.valid ? this.STATUS_VALID : this.STATUS_INVALID, validatorName);
+ if (!validateResult.valid && !verbose) {
+ break;
+ }
}
// ... or a boolean value
else if ('boolean' === typeof validateResult) {
+ $field.data('bv.response.' + validatorName, validateResult);
this.updateStatus(updateAll ? field : $field, validateResult ? this.STATUS_VALID : this.STATUS_INVALID, validatorName);
+ if (!validateResult && !verbose) {
+ break;
+ }
}
}
}
return this;
@@ -886,11 +989,11 @@
var $parent = $field.parents(group),
$message = $field.data('bv.messages'),
$allErrors = $message.find('.help-block[data-bv-validator][data-bv-for="' + field + '"]'),
$errors = validatorName ? $allErrors.filter('[data-bv-validator="' + validatorName + '"]') : $allErrors,
$icon = $parent.find('.form-control-feedback[data-bv-icon-for="' + field + '"]'),
- container = this.options.fields[field].container || this.options.container,
+ container = ('function' === typeof (this.options.fields[field].container || this.options.container)) ? (this.options.fields[field].container || this.options.container).call(this, $field, this) : (this.options.fields[field].container || this.options.container),
isValidField = null;
// Update status
if (validatorName) {
$field.data('bv.result.' + validatorName, status);
@@ -974,26 +1077,28 @@
switch (true) {
// Only show the first error message if it is placed inside a tooltip ...
case ($icon && 'tooltip' === container):
(isValidField === false)
? $icon.css('cursor', 'pointer').tooltip('destroy').tooltip({
+ container: 'body',
html: true,
placement: 'top',
title: $allErrors.filter('[data-bv-result="' + that.STATUS_INVALID + '"]').eq(0).html()
})
- : $icon.css('cursor', '').tooltip('destroy');
+ : $icon.tooltip('hide');
break;
// ... or popover
case ($icon && 'popover' === container):
(isValidField === false)
? $icon.css('cursor', 'pointer').popover('destroy').popover({
+ container: 'body',
content: $allErrors.filter('[data-bv-result="' + that.STATUS_INVALID + '"]').eq(0).html(),
html: true,
placement: 'top',
trigger: 'hover click'
})
- : $icon.css('cursor', '').popover('destroy');
+ : $icon.popover('hide');
break;
default:
(status === this.STATUS_INVALID) ? $errors.show() : $errors.hide();
break;
}
@@ -1098,19 +1203,13 @@
for (var field in map) {
var $f = map[field];
if ($f.data('bv.messages')
.find('.help-block[data-bv-validator][data-bv-for="' + field + '"]')
- .filter(function() {
- var v = $(this).attr('data-bv-validator'),
- f = $(this).attr('data-bv-for');
- return (that.options.fields[f].validators[v].enabled !== false
- && $f.data('bv.result.' + v) && $f.data('bv.result.' + v) !== that.STATUS_VALID);
- })
- .length !== 0)
+ .filter('[data-bv-result="' + this.STATUS_INVALID +'"]')
+ .length > 0)
{
- // The field is not valid
return false;
}
}
return true;
@@ -1204,40 +1303,10 @@
return messages;
},
/**
- * Get the field options
- *
- * @param {String|jQuery} [field] The field name or field element. If it is not set, the method returns the form options
- * @param {String} [validator] The name of validator. It null, the method returns form options
- * @param {String} [option] The option name
- * @return {String|Object}
- */
- getOptions: function(field, validator, option) {
- if (!field) {
- return this.options;
- }
- if ('object' === typeof field) {
- field = field.attr('data-bv-field');
- }
- if (!this.options.fields[field]) {
- return null;
- }
-
- var options = this.options.fields[field];
- if (!validator) {
- return options;
- }
- if (!options.validators || !options.validators[validator]) {
- return null;
- }
-
- return option ? options.validators[validator][option] : options.validators[validator];
- },
-
- /**
* Update the option of a specific validator
*
* @param {String|jQuery} field The field name or field element
* @param {String} validator The validator name
* @param {String} option The option name
@@ -1517,14 +1586,13 @@
/**
* Destroy the plugin
* It will remove all error messages, feedback icons and turn off the events
*/
destroy: function() {
- var field, fields, $field, validator, $icon, container, group;
+ var field, fields, $field, validator, $icon, group;
for (field in this.options.fields) {
fields = this.getFieldElements(field);
- container = this.options.fields[field].container || this.options.container,
group = this.options.fields[field].group || this.options.group;
for (var i = 0; i < fields.length; i++) {
$field = fields.eq(i);
$field
// Remove all error messages
@@ -1541,10 +1609,11 @@
.removeAttr('data-bv-field');
// Remove feedback icons, tooltip/popover container
$icon = $field.parents(group).find('i[data-bv-icon-for="' + field + '"]');
if ($icon) {
+ var container = ('function' === typeof (this.options.fields[field].container || this.options.container)) ? (this.options.fields[field].container || this.options.container).call(this, $field, this) : (this.options.fields[field].container || this.options.container);
switch (container) {
case 'tooltip':
$icon.tooltip('destroy').remove();
break;
case 'popover':
@@ -1558,11 +1627,18 @@
for (validator in this.options.fields[field].validators) {
if ($field.data('bv.dfs.' + validator)) {
$field.data('bv.dfs.' + validator).reject();
}
- $field.removeData('bv.result.' + validator).removeData('bv.dfs.' + validator);
+ $field.removeData('bv.result.' + validator)
+ .removeData('bv.response.' + validator)
+ .removeData('bv.dfs.' + validator);
+
+ // Destroy the validator
+ if ('function' === typeof $.fn.bootstrapValidator.validators[validator].destroy) {
+ $.fn.bootstrapValidator.validators[validator].destroy(this, $field, this.options.fields[field].validators[validator]);
+ }
}
}
}
this.disableSubmitButtons(false); // Enable submit buttons
@@ -1696,11 +1772,19 @@
fieldError: 'error.field.bv',
fieldSuccess: 'success.field.bv',
fieldStatus: 'status.field.bv',
validatorError: 'error.validator.bv',
validatorSuccess: 'success.validator.bv'
- }
+ },
+
+ // Whether to be verbose when validating a field or not.
+ // Possible values:
+ // - true: when a field has multiple validators, all of them will be checked, and respectively - if errors occur in
+ // multiple validators, all of them will be displayed to the user
+ // - false: when a field has multiple validators, validation for this field will be terminated upon the first encountered error.
+ // Thus, only the very first error message related to this field will be displayed to the user
+ verbose: true
};
// Available validators
$.fn.bootstrapValidator.validators = {};
@@ -1958,10 +2042,39 @@
};
}
};
}(window.jQuery));
;(function($) {
+ $.fn.bootstrapValidator.validators.blank = {
+ /**
+ * Placeholder validator that can be used to display a custom validation message
+ * returned from the server
+ * Example:
+ *
+ * (1) a "blank" validator is applied to an input field.
+ * (2) data is entered via the UI that is unable to be validated client-side.
+ * (3) server returns a 400 with JSON data that contains the field that failed
+ * validation and an associated message.
+ * (4) ajax 400 call handler does the following:
+ *
+ * bv.updateMessage(field, 'blank', errorMessage);
+ * bv.updateStatus(field, 'INVALID');
+ *
+ * @see https://github.com/nghuuphuoc/bootstrapvalidator/issues/542
+ * @see https://github.com/nghuuphuoc/bootstrapvalidator/pull/666
+ * @param {BootstrapValidator} validator The validator plugin instance
+ * @param {jQuery} $field Field element
+ * @param {Object} options Can consist of the following keys:
+ * - message: The invalid message
+ * @returns {Boolean}
+ */
+ validate: function(validator, $field, options) {
+ return true;
+ }
+ };
+}(window.jQuery));
+;(function($) {
$.fn.bootstrapValidator.i18n.callback = $.extend($.fn.bootstrapValidator.i18n.callback || {}, {
'default': 'Please enter a valid value'
});
$.fn.bootstrapValidator.validators.callback = {
@@ -1981,23 +2094,24 @@
* // fieldValue is the value of field
* // validator is instance of BootstrapValidator
* // $field is the field element
* }
* - message: The invalid message
- * @returns {Boolean|Deferred}
+ * @returns {Deferred}
*/
validate: function(validator, $field, options) {
- var value = $field.val();
+ var value = $field.val(),
+ dfd = new $.Deferred(),
+ result = { valid: true };
if (options.callback) {
- var dfd = new $.Deferred(),
- response = $.fn.bootstrapValidator.helpers.call(options.callback, [value, validator, $field]);
- dfd.resolve($field, 'callback', 'boolean' === typeof response ? response : response.valid, 'object' === typeof response && response.message ? response.message : null);
- return dfd;
+ var response = $.fn.bootstrapValidator.helpers.call(options.callback, [value, validator, $field]);
+ result = ('boolean' === typeof response) ? { valid: response } : response;
}
- return true;
+ dfd.resolve($field, 'callback', result);
+ return dfd;
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.choice = $.extend($.fn.bootstrapValidator.i18n.choice || {}, {
@@ -2498,21 +2612,28 @@
var value = $field.val();
if (value === '') {
return true;
}
- var compareWith = validator.getFieldElements(options.field);
- if (compareWith === null || compareWith.length === 0) {
- return true;
- }
+ var fields = options.field.split(','),
+ isValid = true;
- if (value !== compareWith.val()) {
- validator.updateStatus(options.field, validator.STATUS_VALID, 'different');
- return true;
- } else {
- return false;
+ for (var i = 0; i < fields.length; i++) {
+ var compareWith = validator.getFieldElements(fields[i]);
+ if (compareWith == null || compareWith.length === 0) {
+ continue;
+ }
+
+ var compareValue = compareWith.val();
+ if (value === compareValue) {
+ isValid = false;
+ } else if (compareValue !== '') {
+ validator.updateStatus(compareWith, validator.STATUS_VALID, 'different');
+ }
}
+
+ return isValid;
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.digits = $.extend($.fn.bootstrapValidator.i18n.digits || {}, {
@@ -2582,32 +2703,88 @@
$.fn.bootstrapValidator.i18n.emailAddress = $.extend($.fn.bootstrapValidator.i18n.emailAddress || {}, {
'default': 'Please enter a valid email address'
});
$.fn.bootstrapValidator.validators.emailAddress = {
+ html5Attributes: {
+ message: 'message',
+ multiple: 'multiple',
+ separator: 'separator'
+ },
+
enableByHtml5: function($field) {
return ('email' === $field.attr('type'));
},
/**
* Return true if and only if the input value is a valid email address
*
* @param {BootstrapValidator} validator Validate plugin instance
* @param {jQuery} $field Field element
* @param {Object} [options]
+ * - multiple: Allow multiple email addresses, separated by a comma or semicolon; default is false.
+ * - separator: Regex for character or characters expected as separator between addresses; default is comma /[,;]/, i.e. comma or semicolon.
* @returns {Boolean}
*/
validate: function(validator, $field, options) {
var value = $field.val();
if (value === '') {
return true;
}
// Email address regular expression
// http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
- var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- return emailRegExp.test(value);
+ var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
+ allowMultiple = options.multiple === true || options.multiple === 'true';
+
+ if (allowMultiple) {
+ var separator = options.separator || /[,;]/,
+ addresses = this._splitEmailAddresses(value, separator);
+
+ for (var i = 0; i < addresses.length; i++) {
+ if (!emailRegExp.test(addresses[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ return emailRegExp.test(value);
+ }
+ },
+
+ _splitEmailAddresses: function(emailAddresses, separator) {
+ var quotedFragments = emailAddresses.split(/"/),
+ quotedFragmentCount = quotedFragments.length,
+ emailAddressArray = [],
+ nextEmailAddress = '';
+
+ for (var i = 0; i < quotedFragmentCount; i++) {
+ if (i % 2 === 0) {
+ var splitEmailAddressFragments = quotedFragments[i].split(separator),
+ splitEmailAddressFragmentCount = splitEmailAddressFragments.length;
+
+ if (splitEmailAddressFragmentCount === 1) {
+ nextEmailAddress += splitEmailAddressFragments[0];
+ } else {
+ emailAddressArray.push(nextEmailAddress + splitEmailAddressFragments[0]);
+
+ for (var j = 1; j < splitEmailAddressFragmentCount - 1; j++) {
+ emailAddressArray.push(splitEmailAddressFragments[j]);
+ }
+ nextEmailAddress = splitEmailAddressFragments[splitEmailAddressFragmentCount - 1];
+ }
+ } else {
+ nextEmailAddress += '"' + quotedFragments[i];
+ if (i < quotedFragmentCount - 1) {
+ nextEmailAddress += '"';
+ }
+ }
+ }
+
+ emailAddressArray.push(nextEmailAddress);
+ return emailAddressArray;
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.file = $.extend($.fn.bootstrapValidator.i18n.file || {}, {
@@ -2616,10 +2793,11 @@
$.fn.bootstrapValidator.validators.file = {
html5Attributes: {
extension: 'extension',
maxsize: 'maxSize',
+ minsize: 'minSize',
message: 'message',
type: 'type'
},
/**
@@ -2628,10 +2806,11 @@
* @param {BootstrapValidator} validator The validator plugin instance
* @param {jQuery} $field Field element
* @param {Object} options Can consist of the following keys:
* - extension: The allowed extensions, separated by a comma
* - maxSize: The maximum size in bytes
+ * - minSize: the minimum size in bytes
* - message: The invalid message
* - type: The allowed MIME type, separated by a comma
* @returns {Boolean}
*/
validate: function(validator, $field, options) {
@@ -2648,11 +2827,16 @@
if (html5) {
// Get FileList instance
var files = $field.get(0).files,
total = files.length;
for (var i = 0; i < total; i++) {
- // Check file size
+ // Check the minSize
+ if (options.minSize && files[i].size < parseInt(options.minSize, 10)) {
+ return false;
+ }
+
+ // Check the maxSize
if (options.maxSize && files[i].size > parseInt(options.maxSize, 10)) {
return false;
}
// Check file extension
@@ -2859,11 +3043,11 @@
CV: 'Cape Verde',
CY: 'Cyprus',
CZ: 'Czech Republic',
DE: 'Germany',
DK: 'Denmark',
- DO: 'Dominican Republic',
+ DO: 'Dominica',
DZ: 'Algeria',
EE: 'Estonia',
ES: 'Spain',
FI: 'Finland',
FO: 'Faroe Islands',
@@ -2901,11 +3085,11 @@
MZ: 'Mozambique',
NL: 'Netherlands',
NO: 'Norway',
PK: 'Pakistan',
PL: 'Poland',
- PS: 'Palestinian',
+ PS: 'Palestine',
PT: 'Portugal',
QA: 'Qatar',
RO: 'Romania',
RS: 'Serbia',
SA: 'Saudi Arabia',
@@ -3080,37 +3264,39 @@
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.id = $.extend($.fn.bootstrapValidator.i18n.id || {}, {
'default': 'Please enter a valid identification number',
countryNotSupported: 'The country code %s is not supported',
- country: 'Please enter a valid %s identification number',
+ country: 'Please enter a valid identification number in %s',
countries: {
BA: 'Bosnia and Herzegovina',
- BG: 'Bulgarian',
- BR: 'Brazilian',
- CH: 'Swiss',
- CL: 'Chilean',
- CZ: 'Czech',
- DK: 'Danish',
- EE: 'Estonian',
- ES: 'Spanish',
- FI: 'Finnish',
- HR: 'Croatian',
- IE: 'Irish',
+ BG: 'Bulgaria',
+ BR: 'Brazil',
+ CH: 'Switzerland',
+ CL: 'Chile',
+ CN: 'China',
+ CZ: 'Czech Republic',
+ DK: 'Denmark',
+ EE: 'Estonia',
+ ES: 'Spain',
+ FI: 'Finland',
+ HR: 'Croatia',
+ IE: 'Ireland',
IS: 'Iceland',
- LT: 'Lithuanian',
- LV: 'Latvian',
+ LT: 'Lithuania',
+ LV: 'Latvia',
ME: 'Montenegro',
- MK: 'Macedonian',
- NL: 'Dutch',
- RO: 'Romanian',
- RS: 'Serbian',
- SE: 'Swedish',
- SI: 'Slovenian',
- SK: 'Slovak',
+ MK: 'Macedonia',
+ NL: 'Netherlands',
+ RO: 'Romania',
+ RS: 'Serbia',
+ SE: 'Sweden',
+ SI: 'Slovenia',
+ SK: 'Slovakia',
SM: 'San Marino',
- ZA: 'South African'
+ TH: 'Thailand',
+ ZA: 'South Africa'
}
});
$.fn.bootstrapValidator.validators.id = {
html5Attributes: {
@@ -3118,12 +3304,12 @@
country: 'country'
},
// Supported country codes
COUNTRY_CODES: [
- 'BA', 'BG', 'BR', 'CH', 'CL', 'CZ', 'DK', 'EE', 'ES', 'FI', 'HR', 'IE', 'IS', 'LT', 'LV', 'ME', 'MK', 'NL',
- 'RO', 'RS', 'SE', 'SI', 'SK', 'SM', 'ZA'
+ 'BA', 'BG', 'BR', 'CH', 'CL', 'CN', 'CZ', 'DK', 'EE', 'ES', 'FI', 'HR', 'IE', 'IS', 'LT', 'LV', 'ME', 'MK', 'NL',
+ 'RO', 'RS', 'SE', 'SI', 'SK', 'SM', 'TH', 'ZA'
],
/**
* Validate identification number in different countries
*
@@ -3393,10 +3579,546 @@
}
return sum + '' === value.charAt(8).toUpperCase();
},
/**
+ * Validate Chinese citizen identification number
+ *
+ * Rules:
+ * - For current 18-digit system (since 1st Oct 1999, defined by GB11643—1999 national standard):
+ * - Digit 0-5: Must be a valid administrative division code of China PR.
+ * - Digit 6-13: Must be a valid YYYYMMDD date of birth. A future date is tolerated.
+ * - Digit 14-16: Order code, any integer.
+ * - Digit 17: An ISO 7064:1983, MOD 11-2 checksum.
+ * Both upper/lower case of X are tolerated.
+ * - For deprecated 15-digit system:
+ * - Digit 0-5: Must be a valid administrative division code of China PR.
+ * - Digit 6-11: Must be a valid YYMMDD date of birth, indicating the year of 19XX.
+ * - Digit 12-14: Order code, any integer.
+ * Lists of valid administrative division codes of China PR can be seen here:
+ * <http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/>
+ * Published and maintained by National Bureau of Statistics of China PR.
+ * NOTE: Current and deprecated codes MUST BOTH be considered valid.
+ * Many Chinese citizens born in once existed administrative divisions!
+ *
+ * @see http://en.wikipedia.org/wiki/Resident_Identity_Card#Identity_card_number
+ * @param {String} value The ID
+ * @returns {Boolean}
+ */
+ _cn: function(value) {
+ // Basic format check (18 or 15 digits, considering X in checksum)
+ value = value.trim();
+ if (!/^\d{15}$/.test(value) && !/^\d{17}[\dXx]{1}$/.test(value)) {
+ return false;
+ }
+
+ // Check China PR Administrative division code
+ var adminDivisionCodes = {
+ 11: {
+ 0: [0],
+ 1: [[0, 9], [11, 17]],
+ 2: [0, 28, 29]
+ },
+ 12: {
+ 0: [0],
+ 1: [[0, 16]],
+ 2: [0, 21, 23, 25]
+ },
+ 13: {
+ 0: [0],
+ 1: [[0, 5], 7, 8, 21, [23, 33], [81, 85]],
+ 2: [[0, 5], [7, 9], [23, 25], 27, 29, 30, 81, 83],
+ 3: [[0, 4], [21, 24]],
+ 4: [[0, 4], 6, 21, [23, 35], 81],
+ 5: [[0, 3], [21, 35], 81, 82],
+ 6: [[0, 4], [21, 38], [81, 84]],
+ 7: [[0, 3], 5, 6, [21, 33]],
+ 8: [[0, 4], [21, 28]],
+ 9: [[0, 3], [21, 30], [81, 84]],
+ 10: [[0, 3], [22, 26], 28, 81, 82],
+ 11: [[0, 2], [21, 28], 81, 82]
+ },
+ 14: {
+ 0: [0],
+ 1: [0, 1, [5, 10], [21, 23], 81],
+ 2: [[0, 3], 11, 12, [21, 27]],
+ 3: [[0, 3], 11, 21, 22],
+ 4: [[0, 2], 11, 21, [23, 31], 81],
+ 5: [[0, 2], 21, 22, 24, 25, 81],
+ 6: [[0, 3], [21, 24]],
+ 7: [[0, 2], [21, 29], 81],
+ 8: [[0, 2], [21, 30], 81, 82],
+ 9: [[0, 2], [21, 32], 81],
+ 10: [[0, 2], [21, 34], 81, 82],
+ 11: [[0, 2], [21, 30], 81, 82],
+ 23: [[0, 3], 22, 23, [25, 30], 32, 33]
+ },
+ 15: {
+ 0: [0],
+ 1: [[0, 5], [21, 25]],
+ 2: [[0, 7], [21, 23]],
+ 3: [[0, 4]],
+ 4: [[0, 4], [21, 26], [28, 30]],
+ 5: [[0, 2], [21, 26], 81],
+ 6: [[0, 2], [21, 27]],
+ 7: [[0, 3], [21, 27], [81, 85]],
+ 8: [[0, 2], [21, 26]],
+ 9: [[0, 2], [21, 29], 81],
+ 22: [[0, 2], [21, 24]],
+ 25: [[0, 2], [22, 31]],
+ 26: [[0, 2], [24, 27], [29, 32], 34],
+ 28: [0, 1, [22, 27]],
+ 29: [0, [21, 23]]
+ },
+ 21: {
+ 0: [0],
+ 1: [[0, 6], [11, 14], [22, 24], 81],
+ 2: [[0, 4], [11, 13], 24, [81, 83]],
+ 3: [[0, 4], 11, 21, 23, 81],
+ 4: [[0, 4], 11, [21, 23]],
+ 5: [[0, 5], 21, 22],
+ 6: [[0, 4], 24, 81, 82],
+ 7: [[0, 3], 11, 26, 27, 81, 82],
+ 8: [[0, 4], 11, 81, 82],
+ 9: [[0, 5], 11, 21, 22],
+ 10: [[0, 5], 11, 21, 81],
+ 11: [[0, 3], 21, 22],
+ 12: [[0, 2], 4, 21, 23, 24, 81, 82],
+ 13: [[0, 3], 21, 22, 24, 81, 82],
+ 14: [[0, 4], 21, 22, 81]
+ },
+ 22: {
+ 0: [0],
+ 1: [[0, 6], 12, 22, [81, 83]],
+ 2: [[0, 4], 11, 21, [81, 84]],
+ 3: [[0, 3], 22, 23, 81, 82],
+ 4: [[0, 3], 21, 22],
+ 5: [[0, 3], 21, 23, 24, 81, 82],
+ 6: [[0, 2], 4, 5, [21, 23], 25, 81],
+ 7: [[0, 2], [21, 24], 81],
+ 8: [[0, 2], 21, 22, 81, 82],
+ 24: [[0, 6], 24, 26]
+ },
+ 23: {
+ 0: [0],
+ 1: [[0, 12], 21, [23, 29], [81, 84]],
+ 2: [[0, 8], 21, [23, 25], 27, [29, 31], 81],
+ 3: [[0, 7], 21, 81, 82],
+ 4: [[0, 7], 21, 22],
+ 5: [[0, 3], 5, 6, [21, 24]],
+ 6: [[0, 6], [21, 24]],
+ 7: [[0, 16], 22, 81],
+ 8: [[0, 5], 11, 22, 26, 28, 33, 81, 82],
+ 9: [[0, 4], 21],
+ 10: [[0, 5], 24, 25, 81, [83, 85]],
+ 11: [[0, 2], 21, 23, 24, 81, 82],
+ 12: [[0, 2], [21, 26], [81, 83]],
+ 27: [[0, 4], [21, 23]]
+ },
+ 31: {
+ 0: [0],
+ 1: [0, 1, [3, 10], [12, 20]],
+ 2: [0, 30]
+ },
+ 32: {
+ 0: [0],
+ 1: [[0, 7], 11, [13, 18], 24, 25],
+ 2: [[0, 6], 11, 81, 82],
+ 3: [[0, 5], 11, 12, [21, 24], 81, 82],
+ 4: [[0, 2], 4, 5, 11, 12, 81, 82],
+ 5: [[0, 9], [81, 85]],
+ 6: [[0, 2], 11, 12, 21, 23, [81, 84]],
+ 7: [0, 1, 3, 5, 6, [21, 24]],
+ 8: [[0, 4], 11, 26, [29, 31]],
+ 9: [[0, 3], [21, 25], 28, 81, 82],
+ 10: [[0, 3], 11, 12, 23, 81, 84, 88],
+ 11: [[0, 2], 11, 12, [81, 83]],
+ 12: [[0, 4], [81, 84]],
+ 13: [[0, 2], 11, [21, 24]]
+ },
+ 33: {
+ 0: [0],
+ 1: [[0, 6], [8, 10], 22, 27, 82, 83, 85],
+ 2: [0, 1, [3, 6], 11, 12, 25, 26, [81, 83]],
+ 3: [[0, 4], 22, 24, [26, 29], 81, 82],
+ 4: [[0, 2], 11, 21, 24, [81, 83]],
+ 5: [[0, 3], [21, 23]],
+ 6: [[0, 2], 21, 24, [81, 83]],
+ 7: [[0, 3], 23, 26, 27, [81, 84]],
+ 8: [[0, 3], 22, 24, 25, 81],
+ 9: [[0, 3], 21, 22],
+ 10: [[0, 4], [21, 24], 81, 82],
+ 11: [[0, 2], [21, 27], 81]
+ },
+ 34: {
+ 0: [0],
+ 1: [[0, 4], 11, [21, 24], 81],
+ 2: [[0, 4], 7, 8, [21, 23], 25],
+ 3: [[0, 4], 11, [21, 23]],
+ 4: [[0, 6], 21],
+ 5: [[0, 4], 6, [21, 23]],
+ 6: [[0, 4], 21],
+ 7: [[0, 3], 11, 21],
+ 8: [[0, 3], 11, [22, 28], 81],
+ 10: [[0, 4], [21, 24]],
+ 11: [[0, 3], 22, [24, 26], 81, 82],
+ 12: [[0, 4], 21, 22, 25, 26, 82],
+ 13: [[0, 2], [21, 24]],
+ 14: [[0, 2], [21, 24]],
+ 15: [[0, 3], [21, 25]],
+ 16: [[0, 2], [21, 23]],
+ 17: [[0, 2], [21, 23]],
+ 18: [[0, 2], [21, 25], 81]
+ },
+ 35: {
+ 0: [0],
+ 1: [[0, 5], 11, [21, 25], 28, 81, 82],
+ 2: [[0, 6], [11, 13]],
+ 3: [[0, 5], 22],
+ 4: [[0, 3], 21, [23, 30], 81],
+ 5: [[0, 5], 21, [24, 27], [81, 83]],
+ 6: [[0, 3], [22, 29], 81],
+ 7: [[0, 2], [21, 25], [81, 84]],
+ 8: [[0, 2], [21, 25], 81],
+ 9: [[0, 2], [21, 26], 81, 82]
+ },
+ 36: {
+ 0: [0],
+ 1: [[0, 5], 11, [21, 24]],
+ 2: [[0, 3], 22, 81],
+ 3: [[0, 2], 13, [21, 23]],
+ 4: [[0, 3], 21, [23, 30], 81, 82],
+ 5: [[0, 2], 21],
+ 6: [[0, 2], 22, 81],
+ 7: [[0, 2], [21, 35], 81, 82],
+ 8: [[0, 3], [21, 30], 81],
+ 9: [[0, 2], [21, 26], [81, 83]],
+ 10: [[0, 2], [21, 30]],
+ 11: [[0, 2], [21, 30], 81]
+ },
+ 37: {
+ 0: [0],
+ 1: [[0, 5], 12, 13, [24, 26], 81],
+ 2: [[0, 3], 5, [11, 14], [81, 85]],
+ 3: [[0, 6], [21, 23]],
+ 4: [[0, 6], 81],
+ 5: [[0, 3], [21, 23]],
+ 6: [[0, 2], [11, 13], 34, [81, 87]],
+ 7: [[0, 5], 24, 25, [81, 86]],
+ 8: [[0, 2], 11, [26, 32], [81, 83]],
+ 9: [[0, 3], 11, 21, 23, 82, 83],
+ 10: [[0, 2], [81, 83]],
+ 11: [[0, 3], 21, 22],
+ 12: [[0, 3]],
+ 13: [[0, 2], 11, 12, [21, 29]],
+ 14: [[0, 2], [21, 28], 81, 82],
+ 15: [[0, 2], [21, 26], 81],
+ 16: [[0, 2], [21, 26]],
+ 17: [[0, 2], [21, 28]]
+ },
+ 41: {
+ 0: [0],
+ 1: [[0, 6], 8, 22, [81, 85]],
+ 2: [[0, 5], 11, [21, 25]],
+ 3: [[0, 7], 11, [22, 29], 81],
+ 4: [[0, 4], 11, [21, 23], 25, 81, 82],
+ 5: [[0, 3], 5, 6, 22, 23, 26, 27, 81],
+ 6: [[0, 3], 11, 21, 22],
+ 7: [[0, 4], 11, 21, [24, 28], 81, 82],
+ 8: [[0, 4], 11, [21, 23], 25, [81, 83]],
+ 9: [[0, 2], 22, 23, [26, 28]],
+ 10: [[0, 2], [23, 25], 81, 82],
+ 11: [[0, 4], [21, 23]],
+ 12: [[0, 2], 21, 22, 24, 81, 82],
+ 13: [[0, 3], [21, 30], 81],
+ 14: [[0, 3], [21, 26], 81],
+ 15: [[0, 3], [21, 28]],
+ 16: [[0, 2], [21, 28], 81],
+ 17: [[0, 2], [21, 29]],
+ 90: [0, 1]
+ },
+ 42: {
+ 0: [0],
+ 1: [[0, 7], [11, 17]],
+ 2: [[0, 5], 22, 81],
+ 3: [[0, 3], [21, 25], 81],
+ 5: [[0, 6], [25, 29], [81, 83]],
+ 6: [[0, 2], 6, 7, [24, 26], [82, 84]],
+ 7: [[0, 4]],
+ 8: [[0, 2], 4, 21, 22, 81],
+ 9: [[0, 2], [21, 23], 81, 82, 84],
+ 10: [[0, 3], [22, 24], 81, 83, 87],
+ 11: [[0, 2], [21, 27], 81, 82],
+ 12: [[0, 2], [21, 24], 81],
+ 13: [[0, 3], 21, 81],
+ 28: [[0, 2], 22, 23, [25, 28]],
+ 90: [0, [4, 6], 21]
+ },
+ 43: {
+ 0: [0],
+ 1: [[0, 5], 11, 12, 21, 22, 24, 81],
+ 2: [[0, 4], 11, 21, [23, 25], 81],
+ 3: [[0, 2], 4, 21, 81, 82],
+ 4: [0, 1, [5, 8], 12, [21, 24], 26, 81, 82],
+ 5: [[0, 3], 11, [21, 25], [27, 29], 81],
+ 6: [[0, 3], 11, 21, 23, 24, 26, 81, 82],
+ 7: [[0, 3], [21, 26], 81],
+ 8: [[0, 2], 11, 21, 22],
+ 9: [[0, 3], [21, 23], 81],
+ 10: [[0, 3], [21, 28], 81],
+ 11: [[0, 3], [21, 29]],
+ 12: [[0, 2], [21, 30], 81],
+ 13: [[0, 2], 21, 22, 81, 82],
+ 31: [0, 1, [22, 27], 30]
+ },
+ 44: {
+ 0: [0],
+ 1: [[0, 7], [11, 16], 83, 84],
+ 2: [[0, 5], 21, 22, 24, 29, 32, 33, 81, 82],
+ 3: [0, 1, [3, 8]],
+ 4: [[0, 4]],
+ 5: [0, 1, [6, 15], 23, 82, 83],
+ 6: [0, 1, [4, 8]],
+ 7: [0, 1, [3, 5], 81, [83, 85]],
+ 8: [[0, 4], 11, 23, 25, [81, 83]],
+ 9: [[0, 3], 23, [81, 83]],
+ 12: [[0, 3], [23, 26], 83, 84],
+ 13: [[0, 3], [22, 24], 81],
+ 14: [[0, 2], [21, 24], 26, 27, 81],
+ 15: [[0, 2], 21, 23, 81],
+ 16: [[0, 2], [21, 25]],
+ 17: [[0, 2], 21, 23, 81],
+ 18: [[0, 3], 21, 23, [25, 27], 81, 82],
+ 19: [0],
+ 20: [0],
+ 51: [[0, 3], 21, 22],
+ 52: [[0, 3], 21, 22, 24, 81],
+ 53: [[0, 2], [21, 23], 81]
+ },
+ 45: {
+ 0: [0],
+ 1: [[0, 9], [21, 27]],
+ 2: [[0, 5], [21, 26]],
+ 3: [[0, 5], 11, 12, [21, 32]],
+ 4: [0, 1, [3, 6], 11, [21, 23], 81],
+ 5: [[0, 3], 12, 21],
+ 6: [[0, 3], 21, 81],
+ 7: [[0, 3], 21, 22],
+ 8: [[0, 4], 21, 81],
+ 9: [[0, 3], [21, 24], 81],
+ 10: [[0, 2], [21, 31]],
+ 11: [[0, 2], [21, 23]],
+ 12: [[0, 2], [21, 29], 81],
+ 13: [[0, 2], [21, 24], 81],
+ 14: [[0, 2], [21, 25], 81]
+ },
+ 46: {
+ 0: [0],
+ 1: [0, 1, [5, 8]],
+ 2: [0, 1],
+ 3: [0, [21, 23]],
+ 90: [[0, 3], [5, 7], [21, 39]]
+ },
+ 50: {
+ 0: [0],
+ 1: [[0, 19]],
+ 2: [0, [22, 38], [40, 43]],
+ 3: [0, [81, 84]]
+ },
+ 51: {
+ 0: [0],
+ 1: [0, 1, [4, 8], [12, 15], [21, 24], 29, 31, 32, [81, 84]],
+ 3: [[0, 4], 11, 21, 22],
+ 4: [[0, 3], 11, 21, 22],
+ 5: [[0, 4], 21, 22, 24, 25],
+ 6: [0, 1, 3, 23, 26, [81, 83]],
+ 7: [0, 1, 3, 4, [22, 27], 81],
+ 8: [[0, 2], 11, 12, [21, 24]],
+ 9: [[0, 4], [21, 23]],
+ 10: [[0, 2], 11, 24, 25, 28],
+ 11: [[0, 2], [11, 13], 23, 24, 26, 29, 32, 33, 81],
+ 13: [[0, 4], [21, 25], 81],
+ 14: [[0, 2], [21, 25]],
+ 15: [[0, 3], [21, 29]],
+ 16: [[0, 3], [21, 23], 81],
+ 17: [[0, 3], [21, 25], 81],
+ 18: [[0, 3], [21, 27]],
+ 19: [[0, 3], [21, 23]],
+ 20: [[0, 2], 21, 22, 81],
+ 32: [0, [21, 33]],
+ 33: [0, [21, 38]],
+ 34: [0, 1, [22, 37]]
+ },
+ 52: {
+ 0: [0],
+ 1: [[0, 3], [11, 15], [21, 23], 81],
+ 2: [0, 1, 3, 21, 22],
+ 3: [[0, 3], [21, 30], 81, 82],
+ 4: [[0, 2], [21, 25]],
+ 5: [[0, 2], [21, 27]],
+ 6: [[0, 3], [21, 28]],
+ 22: [0, 1, [22, 30]],
+ 23: [0, 1, [22, 28]],
+ 24: [0, 1, [22, 28]],
+ 26: [0, 1, [22, 36]],
+ 27: [[0, 2], 22, 23, [25, 32]]
+ },
+ 53: {
+ 0: [0],
+ 1: [[0, 3], [11, 14], 21, 22, [24, 29], 81],
+ 3: [[0, 2], [21, 26], 28, 81],
+ 4: [[0, 2], [21, 28]],
+ 5: [[0, 2], [21, 24]],
+ 6: [[0, 2], [21, 30]],
+ 7: [[0, 2], [21, 24]],
+ 8: [[0, 2], [21, 29]],
+ 9: [[0, 2], [21, 27]],
+ 23: [0, 1, [22, 29], 31],
+ 25: [[0, 4], [22, 32]],
+ 26: [0, 1, [21, 28]],
+ 27: [0, 1, [22, 30]], 28: [0, 1, 22, 23],
+ 29: [0, 1, [22, 32]],
+ 31: [0, 2, 3, [22, 24]],
+ 34: [0, [21, 23]],
+ 33: [0, 21, [23, 25]],
+ 35: [0, [21, 28]]
+ },
+ 54: {
+ 0: [0],
+ 1: [[0, 2], [21, 27]],
+ 21: [0, [21, 29], 32, 33],
+ 22: [0, [21, 29], [31, 33]],
+ 23: [0, 1, [22, 38]],
+ 24: [0, [21, 31]],
+ 25: [0, [21, 27]],
+ 26: [0, [21, 27]]
+ },
+ 61: {
+ 0: [0],
+ 1: [[0, 4], [11, 16], 22, [24, 26]],
+ 2: [[0, 4], 22],
+ 3: [[0, 4], [21, 24], [26, 31]],
+ 4: [[0, 4], [22, 31], 81],
+ 5: [[0, 2], [21, 28], 81, 82],
+ 6: [[0, 2], [21, 32]],
+ 7: [[0, 2], [21, 30]],
+ 8: [[0, 2], [21, 31]],
+ 9: [[0, 2], [21, 29]],
+ 10: [[0, 2], [21, 26]]
+ },
+ 62: {
+ 0: [0],
+ 1: [[0, 5], 11, [21, 23]],
+ 2: [0, 1],
+ 3: [[0, 2], 21],
+ 4: [[0, 3], [21, 23]],
+ 5: [[0, 3], [21, 25]],
+ 6: [[0, 2], [21, 23]],
+ 7: [[0, 2], [21, 25]],
+ 8: [[0, 2], [21, 26]],
+ 9: [[0, 2], [21, 24], 81, 82],
+ 10: [[0, 2], [21, 27]],
+ 11: [[0, 2], [21, 26]],
+ 12: [[0, 2], [21, 28]],
+ 24: [0, 21, [24, 29]],
+ 26: [0, 21, [23, 30]],
+ 29: [0, 1, [21, 27]],
+ 30: [0, 1, [21, 27]]
+ },
+ 63: {
+ 0: [0],
+ 1: [[0, 5], [21, 23]],
+ 2: [0, 2, [21, 25]],
+ 21: [0, [21, 23], [26, 28]],
+ 22: [0, [21, 24]],
+ 23: [0, [21, 24]],
+ 25: [0, [21, 25]],
+ 26: [0, [21, 26]],
+ 27: [0, 1, [21, 26]],
+ 28: [[0, 2], [21, 23]]
+ },
+ 64: {
+ 0: [0],
+ 1: [0, 1, [4, 6], 21, 22, 81],
+ 2: [[0, 3], 5, [21, 23]],
+ 3: [[0, 3], [21, 24], 81],
+ 4: [[0, 2], [21, 25]],
+ 5: [[0, 2], 21, 22]
+ },
+ 65: {
+ 0: [0],
+ 1: [[0, 9], 21],
+ 2: [[0, 5]],
+ 21: [0, 1, 22, 23],
+ 22: [0, 1, 22, 23],
+ 23: [[0, 3], [23, 25], 27, 28],
+ 28: [0, 1, [22, 29]],
+ 29: [0, 1, [22, 29]],
+ 30: [0, 1, [22, 24]], 31: [0, 1, [21, 31]],
+ 32: [0, 1, [21, 27]],
+ 40: [0, 2, 3, [21, 28]],
+ 42: [[0, 2], 21, [23, 26]],
+ 43: [0, 1, [21, 26]],
+ 90: [[0, 4]], 27: [[0, 2], 22, 23]
+ },
+ 71: { 0: [0] },
+ 81: { 0: [0] },
+ 82: { 0: [0] }
+ };
+
+ var provincial = parseInt(value.substr(0, 2), 10),
+ prefectural = parseInt(value.substr(2, 2), 10),
+ county = parseInt(value.substr(4, 2), 10);
+
+ if (!adminDivisionCodes[provincial] || !adminDivisionCodes[provincial][prefectural]) {
+ return false;
+ }
+ var inRange = false,
+ rangeDef = adminDivisionCodes[provincial][prefectural];
+ for (var i = 0; i < rangeDef.length; i++) {
+ if (($.isArray(rangeDef[i]) && rangeDef[i][0] <= county && county <= rangeDef[i][1])
+ || (!$.isArray(rangeDef[i]) && county === rangeDef[i]))
+ {
+ inRange = true;
+ break;
+ }
+ }
+
+ if (!inRange) {
+ return false;
+ }
+
+ // Check date of birth
+ var dob;
+ if (value.length === 18) {
+ dob = value.substr(6, 8);
+ } else /* length == 15 */ {
+ dob = '19' + value.substr(6, 6);
+ }
+ var year = parseInt(dob.substr(0, 4), 10),
+ month = parseInt(dob.substr(4, 2), 10),
+ day = parseInt(dob.substr(6, 2), 10);
+ if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
+ return false;
+ }
+
+ // Check checksum (18-digit system only)
+ if (value.length === 18) {
+ var sum = 0,
+ weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
+ for (i = 0; i < 17; i++) {
+ sum += parseInt(value.charAt(i), 10) * weight[i];
+ }
+ sum = (12 - (sum % 11)) % 11;
+ var checksum = (value.charAt(17).toUpperCase() !== 'X') ? parseInt(value.charAt(17), 10) : 10;
+ return checksum === sum;
+ }
+
+ return true;
+ },
+
+ /**
* Validate Czech national identification number (RC)
* Examples:
* - Valid: 7103192745, 991231123
* - Invalid: 1103492745, 590312123
*
@@ -3863,10 +4585,33 @@
_sm: function(value) {
return /^\d{5}$/.test(value);
},
/**
+ * Validate Thailand citizen number
+ * Examples:
+ * - Valid: 7145620509547, 3688699975685, 2368719339716
+ * - Invalid: 1100800092310
+ *
+ * @see http://en.wikipedia.org/wiki/National_identification_number#Thailand
+ * @param {String} value The ID
+ * @returns {Boolean}
+ */
+ _th: function(value) {
+ if (value.length !== 13) {
+ return false;
+ }
+
+ var sum = 0;
+ for (var i = 0; i < 12; i++) {
+ sum += parseInt(value.charAt(i), 10) * (13 - i);
+ }
+
+ return (11 - sum % 11) % 10 === parseInt(value.charAt(12), 10);
+ },
+
+ /**
* Validate South African ID
* Example:
* - Valid: 8001015009087
* - Invalid: 8001015009287, 8001015009086
*
@@ -4103,11 +4848,11 @@
break;
case (options.ipv4 && options.ipv6):
/* falls through */
default:
- valid = ipv4Regex.test(value) && ipv6Regex.test(value);
+ valid = ipv4Regex.test(value) || ipv6Regex.test(value);
message = options.message || $.fn.bootstrapValidator.i18n.ip['default'];
break;
}
return {
@@ -4564,10 +5309,14 @@
.getFieldElements($field.attr('data-bv-field'))
.filter(':checked')
.length > 0;
}
+ if ('number' === type && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+ return true;
+ }
+
return $.trim($field.val()) !== '';
}
};
}(window.jQuery));
;(function($) {
@@ -4618,27 +5367,35 @@
'default': 'Please enter a valid phone number',
countryNotSupported: 'The country code %s is not supported',
country: 'Please enter a valid phone number in %s',
countries: {
BR: 'Brazil',
+ CN: 'China',
+ CZ: 'Czech Republic',
+ DK: 'Denmark',
ES: 'Spain',
FR: 'France',
GB: 'United Kingdom',
MA: 'Morocco',
PK: 'Pakistan',
- US: 'USA'
+ RO: 'Romania',
+ RU: 'Russia',
+ SK: 'Slovakia',
+ TH: 'Thailand',
+ US: 'USA',
+ VE: 'Venezuela'
}
});
$.fn.bootstrapValidator.validators.phone = {
html5Attributes: {
message: 'message',
country: 'country'
},
// The supported countries
- COUNTRY_CODES: ['BR', 'ES', 'FR', 'GB', 'MA', 'PK', 'US'],
+ COUNTRY_CODES: ['BR', 'CN', 'CZ', 'DK', 'ES', 'FR', 'GB', 'MA', 'PK', 'RO', 'RU', 'SK', 'TH', 'US', 'VE'],
/**
* Return true if the input value contains a valid phone number for the country
* selected in the options
*
@@ -4679,10 +5436,30 @@
// Test: http://regexr.com/399m1
value = $.trim(value);
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);
break;
+ case 'CN':
+ // http://regexr.com/39dq4
+ value = $.trim(value);
+ isValid = (/^((00|\+)?(86(?:-| )))?((\d{11})|(\d{3}[- ]{1}\d{4}[- ]{1}\d{4})|((\d{2,4}[- ]){1}(\d{7,8}|(\d{3,4}[- ]{1}\d{4}))([- ]{1}\d{1,4})?))$/).test(value);
+ break;
+
+ case 'CZ':
+ // Test: http://regexr.com/39hhl
+ isValid = /^(((00)([- ]?)|\+)(420)([- ]?))?((\d{3})([- ]?)){2}(\d{3})$/.test(value);
+ break;
+
+ case 'DK':
+ // Mathing DK phone numbers with country code in 1 of 3 formats and an
+ // 8 digit phone number not starting with a 0 or 1. Can have 1 space
+ // between each character except inside the country code.
+ // Test: http://regex101.com/r/sS8fO4/1
+ value = $.trim(value);
+ isValid = (/^(\+45|0045|\(45\))?\s?[2-9](\s?\d){7}$/).test(value);
+ break;
+
case 'ES':
// http://regex101.com/r/rB9mA9/1
value = $.trim(value);
isValid = (/^(?:(?:(?:\+|00)34\D?))?(?:9|6)(?:\d\D?){8}$/).test(value);
break;
@@ -4704,17 +5481,44 @@
// http://en.wikipedia.org/wiki/Telephone_numbers_in_Morocco
// Test: http://regexr.com/399n8
value = $.trim(value);
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);
break;
-
+
case 'PK':
// http://regex101.com/r/yH8aV9/2
value = $.trim(value);
isValid = (/^0?3[0-9]{2}[0-9]{7}$/).test(value);
break;
-
+
+ case 'RO':
+ // All mobile network and land line
+ // http://regexr.com/39fv1
+ isValid = (/^(\+4|)?(07[0-8]{1}[0-9]{1}|02[0-9]{2}|03[0-9]{2}){1}?(\s|\.|\-)?([0-9]{3}(\s|\.|\-|)){2}$/g).test(value);
+ break;
+
+ case 'RU':
+ // http://regex101.com/r/gW7yT5/5
+ isValid = (/^((8|\+7|007)[\-\.\/ ]?)?([\(\/\.]?\d{3}[\)\/\.]?[\-\.\/ ]?)?[\d\-\.\/ ]{7,10}$/g).test(value);
+ break;
+
+ case 'SK':
+ // Test: http://regexr.com/39hhl
+ isValid = /^(((00)([- ]?)|\+)(420)([- ]?))?((\d{3})([- ]?)){2}(\d{3})$/.test(value);
+ break;
+
+ case 'TH':
+ // http://regex101.com/r/vM5mZ4/2
+ isValid = (/^0\(?([6|8-9]{2})*-([0-9]{3})*-([0-9]{4})$/).test(value);
+ break;
+
+ case 'VE':
+ // http://regex101.com/r/eM2yY0/6
+ value = $.trim(value);
+ isValid = (/^0(?:2(?:12|4[0-9]|5[1-9]|6[0-9]|7[0-8]|8[1-35-8]|9[1-5]|3[45789])|4(?:1[246]|2[46]))\d{7}$/).test(value);
+ break;
+
case 'US':
/* falls through */
default:
// Make sure US phone numbers have 10 digits
// May start with 1, +1, or 1-; should discard
@@ -4782,14 +5586,25 @@
$.fn.bootstrapValidator.validators.remote = {
html5Attributes: {
message: 'message',
name: 'name',
type: 'type',
- url: 'url'
+ url: 'url',
+ delay: 'delay'
},
/**
+ * Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method)
+ */
+ destroy: function(validator, $field, options) {
+ if ($field.data('bv.remote.timer')) {
+ clearTimeout($field.data('bv.remote.timer'));
+ $field.removeData('bv.remote.timer');
+ }
+ },
+
+ /**
* Request a remote server to check the input value
*
* @param {BootstrapValidator} validator Plugin instance
* @param {jQuery} $field Field element
* @param {Object} options Can consist of the following keys:
@@ -4797,25 +5612,28 @@
* - type {String} [optional] Can be GET or POST (default)
* - data {Object|Function} [optional]: By default, it will take the value
* {
* <fieldName>: <fieldValue>
* }
+ * - delay
* - name {String} [optional]: Override the field name for the request.
* - message: The invalid message
* - headers: Additional headers
- * @returns {Boolean|Deferred}
+ * @returns {Deferred}
*/
validate: function(validator, $field, options) {
- var value = $field.val();
+ var value = $field.val(),
+ dfd = new $.Deferred();
if (value === '') {
- return true;
+ dfd.resolve($field, 'remote', { valid: true });
+ return dfd;
}
var name = $field.attr('data-bv-field'),
data = options.data || {},
url = options.url,
- type = options.type || 'POST',
+ type = options.type || 'GET',
headers = options.headers || {};
// Support dynamic data
if ('function' === typeof data) {
data = data.call(this, validator);
@@ -4825,28 +5643,42 @@
if ('function' === typeof url) {
url = url.call(this, validator);
}
data[options.name || name] = value;
+ function runCallback() {
+ var xhr = $.ajax({
+ type: type,
+ headers: headers,
+ url: url,
+ dataType: 'json',
+ data: data
+ });
+ xhr.then(function(response) {
+ response.valid = response.valid === true || response.valid === 'true';
+ dfd.resolve($field, 'remote', response);
+ });
- var dfd = new $.Deferred();
- var xhr = $.ajax({
- type: type,
- headers: headers,
- url: url,
- dataType: 'json',
- data: data
- });
- xhr.then(function(response) {
- dfd.resolve($field, 'remote', response.valid === true || response.valid === 'true', response.message ? response.message : null);
- });
+ dfd.fail(function() {
+ xhr.abort();
+ });
- dfd.fail(function() {
- xhr.abort();
- });
+ return dfd;
+ }
+
+ if (options.delay) {
+ // Since the form might have multiple fields with the same name
+ // I have to attach the timer to the field element
+ if ($field.data('bv.remote.timer')) {
+ clearTimeout($field.data('bv.remote.timer'));
+ }
- return dfd;
+ $field.data('bv.remote.timer', setTimeout(runCallback, options.delay));
+ return dfd;
+ } else {
+ return runCallback();
+ }
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.rtn = $.extend($.fn.bootstrapValidator.i18n.rtn || {}, {
@@ -5106,18 +5938,21 @@
min: 'min',
max: 'max'
},
enableByHtml5: function($field) {
- var maxLength = $field.attr('maxlength');
+ var options = {},
+ maxLength = $field.attr('maxlength'),
+ minLength = $field.attr('minlength');
if (maxLength) {
- return {
- max: parseInt(maxLength, 10)
- };
+ options.max = parseInt(maxLength, 10);
}
+ if (minLength) {
+ options.min = parseInt(minLength, 10);
+ }
- return false;
+ return $.isEmptyObject(options) ? false : options;
},
/**
* Check if the length of element value is less or more than given number
*
@@ -5179,11 +6014,12 @@
});
$.fn.bootstrapValidator.validators.uri = {
html5Attributes: {
message: 'message',
- allowlocal: 'allowLocal'
+ allowlocal: 'allowLocal',
+ protocol: 'protocol'
},
enableByHtml5: function($field) {
return ('url' === $field.attr('type'));
},
@@ -5194,10 +6030,11 @@
* @param {BootstrapValidator} validator The validator plugin instance
* @param {jQuery} $field Field element
* @param {Object} options
* - message: The error message
* - allowLocal: Allow the private and local network IP. Default to false
+ * - protocol: The protocols, separated by a comma. Default to "http, https, ftp"
* @returns {Boolean}
*/
validate: function(validator, $field, options) {
var value = $field.val();
if (value === '') {
@@ -5231,15 +6068,18 @@
// (since they are broadcast/network addresses)
//
// - Added exclusion of private, reserved and/or local networks ranges
// unless `allowLocal` is true
//
+ // - Added possibility of choosing a custom protocol
+ //
var allowLocal = options.allowLocal === true || options.allowLocal === 'true',
+ protocol = (options.protocol || 'http, https, ftp').split(',').join('|').replace(/\s/g, ''),
urlExp = new RegExp(
"^" +
// protocol identifier
- "(?:(?:https?|ftp)://)" +
+ "(?:(?:" + protocol + ")://)" +
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
@@ -5269,11 +6109,11 @@
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/[^\\s]*)?" +
"$", "i"
- );
+ );
return urlExp.test(value);
}
};
}(window.jQuery));
@@ -5325,48 +6165,49 @@
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.vat = $.extend($.fn.bootstrapValidator.i18n.vat || {}, {
'default': 'Please enter a valid VAT number',
countryNotSupported: 'The country code %s is not supported',
- country: 'Please enter a valid %s VAT number',
+ country: 'Please enter a valid VAT number in %s',
countries: {
- AT: 'Austrian',
- BE: 'Belgian',
- BG: 'Bulgarian',
- BR: 'Brazilian',
- CH: 'Swiss',
- CY: 'Cypriot',
- CZ: 'Czech',
- DE: 'German',
- DK: 'Danish',
- EE: 'Estonian',
- ES: 'Spanish',
- FI: 'Finnish',
- FR: 'French',
+ AT: 'Austria',
+ BE: 'Belgium',
+ BG: 'Bulgaria',
+ BR: 'Brazil',
+ CH: 'Switzerland',
+ CY: 'Cyprus',
+ CZ: 'Czech Republic',
+ DE: 'Germany',
+ DK: 'Denmark',
+ EE: 'Estonia',
+ ES: 'Spain',
+ FI: 'Finland',
+ FR: 'France',
GB: 'United Kingdom',
GR: 'Greek',
EL: 'Greek',
- HU: 'Hungarian',
- HR: 'Croatian',
- IE: 'Irish',
+ HU: 'Hungary',
+ HR: 'Croatia',
+ IE: 'Ireland',
IS: 'Iceland',
- IT: 'Italian',
- LT: 'Lithuanian',
+ IT: 'Italy',
+ LT: 'Lithuania',
LU: 'Luxembourg',
- LV: 'Latvian',
- MT: 'Maltese',
- NL: 'Dutch',
- NO: 'Norwegian',
- PL: 'Polish',
- PT: 'Portuguese',
- RO: 'Romanian',
- RU: 'Russian',
- RS: 'Serbian',
- SE: 'Swedish',
- SI: 'Slovenian',
- SK: 'Slovak',
- ZA: 'South African'
+ LV: 'Latvia',
+ MT: 'Malta',
+ NL: 'Netherlands',
+ NO: 'Norway',
+ PL: 'Poland',
+ PT: 'Portugal',
+ RO: 'Romania',
+ RU: 'Russia',
+ RS: 'Serbia',
+ SE: 'Sweden',
+ SI: 'Slovenia',
+ SK: 'Slovakia',
+ VE: 'Venezuela',
+ ZA: 'South Africa'
}
});
$.fn.bootstrapValidator.validators.vat = {
html5Attributes: {
@@ -5375,11 +6216,12 @@
},
// Supported country codes
COUNTRY_CODES: [
'AT', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI', 'FR', 'GB', 'GR', 'HR', 'HU',
- 'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'RS', 'SE', 'SK', 'SI', 'ZA'
+ 'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'RS', 'SE', 'SK', 'SI', 'VE',
+ 'ZA'
],
/**
* Validate an European VAT number
*
@@ -5434,19 +6276,21 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_at: function(value) {
- if (!/^ATU[0-9]{8}$/.test(value)) {
+ if (/^ATU[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^U[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(3);
+ value = value.substr(1);
var sum = 0,
weight = [1, 2, 1, 2, 1, 2, 1],
temp = 0;
-
for (var i = 0; i < 7; i++) {
temp = parseInt(value.charAt(i), 10) * weight[i];
if (temp > 9) {
temp = Math.floor(temp / 10) + temp % 10;
}
@@ -5469,19 +6313,20 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_be: function(value) {
- if (!/^BE[0]{0,1}[0-9]{9}$/.test(value)) {
+ if (/^BE[0]{0,1}[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0]{0,1}[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
if (value.length === 9) {
value = '0' + value;
}
-
if (value.substr(1, 1) === '0') {
return false;
}
var sum = parseInt(value.substr(0, 8), 10) + parseInt(value.substr(8, 2), 10);
@@ -5499,15 +6344,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_bg: function(value) {
- if (!/^BG[0-9]{9,10}$/.test(value)) {
+ if (/^BG[0-9]{9,10}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9,10}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0, i = 0;
// Legal entities
if (value.length === 9) {
for (i = 0; i < 8; i++) {
@@ -5646,15 +6493,18 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_ch: function(value) {
- if (!/^CHE[0-9]{9}(MWST)?$/.test(value)) {
+ if (/^CHE[0-9]{9}(MWST)?$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^E[0-9]{9}(MWST)?$/.test(value)) {
return false;
}
- value = value.substr(3);
+ value = value.substr(1);
var sum = 0,
weight = [5, 4, 3, 2, 7, 6, 5, 4];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
@@ -5678,16 +6528,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_cy: function(value) {
- if (!/^CY[0-5|9]{1}[0-9]{7}[A-Z]{1}$/.test(value)) {
+ if (/^CY[0-5|9]{1}[0-9]{7}[A-Z]{1}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-5|9]{1}[0-9]{7}[A-Z]{1}$/.test(value)) {
return false;
}
- value = value.substr(2);
-
// Do not allow to start with "12"
if (value.substr(0, 2) === '12') {
return false;
}
@@ -5722,16 +6573,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_cz: function(value) {
- if (!/^CZ[0-9]{8,10}$/.test(value)) {
+ if (/^CZ[0-9]{8,10}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8,10}$/.test(value)) {
return false;
}
- value = value.substr(2);
-
var sum = 0,
i = 0;
if (value.length === 8) {
// Do not allow to start with '9'
if (value.charAt(0) + '' === '9') {
@@ -5809,15 +6661,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_de: function(value) {
- if (!/^DE[0-9]{9}$/.test(value)) {
+ if (/^DE[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
return $.fn.bootstrapValidator.helpers.mod11And10(value);
},
/**
* Validate Danish VAT number
@@ -5827,15 +6681,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_dk: function(value) {
- if (!/^DK[0-9]{8}$/.test(value)) {
+ if (/^DK[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [2, 7, 6, 5, 4, 3, 2, 1];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
@@ -5851,18 +6707,19 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_ee: function(value) {
- if (!/^EE[0-9]{9}$/.test(value)) {
+ if (/^EE[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [3, 7, 1, 3, 7, 1, 3, 7, 1];
-
for (var i = 0; i < 9; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
return (sum % 10 === 0);
@@ -5881,15 +6738,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_es: function(value) {
- if (!/^ES[0-9A-Z][0-9]{7}[0-9A-Z]$/.test(value)) {
+ if (/^ES[0-9A-Z][0-9]{7}[0-9A-Z]$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9A-Z][0-9]{7}[0-9A-Z]$/.test(value)) {
return false;
}
- value = value.substr(2);
var dni = function(value) {
var check = parseInt(value.substr(0, 8), 10);
check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
return (check + '' === value.substr(8, 1));
},
@@ -5945,18 +6804,19 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_fi: function(value) {
- if (!/^FI[0-9]{8}$/.test(value)) {
+ if (/^FI[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [7, 9, 10, 5, 8, 4, 2, 1];
-
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
return (sum % 11 === 0);
@@ -5972,16 +6832,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_fr: function(value) {
- if (!/^FR[0-9A-Z]{2}[0-9]{9}$/.test(value)) {
+ if (/^FR[0-9A-Z]{2}[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9A-Z]{2}[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
-
if (!$.fn.bootstrapValidator.helpers.luhn(value.substr(2))) {
return false;
}
if (/^[0-9]{2}$/.test(value.substr(0, 2))) {
@@ -6009,20 +6870,27 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_gb: function(value) {
- if (!/^GB[0-9]{9}$/.test(value) /* Standard */
- && !/^GB[0-9]{12}$/.test(value) /* Branches */
- && !/^GBGD[0-9]{3}$/.test(value) /* Government department */
- && !/^GBHA[0-9]{3}$/.test(value) /* Health authority */
- && !/^GB(GD|HA)8888[0-9]{5}$/.test(value))
+ if (/^GB[0-9]{9}$/.test(value) /* Standard */
+ || /^GB[0-9]{12}$/.test(value) /* Branches */
+ || /^GBGD[0-9]{3}$/.test(value) /* Government department */
+ || /^GBHA[0-9]{3}$/.test(value) /* Health authority */
+ || /^GB(GD|HA)8888[0-9]{5}$/.test(value))
{
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)
+ && !/^[0-9]{12}$/.test(value)
+ && !/^GD[0-9]{3}$/.test(value)
+ && !/^HA[0-9]{3}$/.test(value)
+ && !/^(GD|HA)8888[0-9]{5}$/.test(value))
+ {
return false;
}
- value = value.substr(2);
var length = value.length;
if (length === 5) {
var firstTwo = value.substr(0, 2),
lastThree = parseInt(value.substr(2), 10);
return ('GD' === firstTwo && lastThree < 500) || ('HA' === firstTwo && lastThree >= 500);
@@ -6059,15 +6927,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_gr: function(value) {
- if (!/^GR[0-9]{9}$/.test(value)) {
+ if (/^(GR|EL)[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
if (value.length === 8) {
value = '0' + value;
}
var sum = 0,
@@ -6080,15 +6950,10 @@
return (sum + '' === value.substr(8, 1));
},
// EL is traditionally prefix of Greek VAT numbers
_el: function(value) {
- if (!/^EL[0-9]{9}$/.test(value)) {
- return false;
- }
-
- value = 'GR' + value.substr(2);
return this._gr(value);
},
/**
* Validate Hungarian VAT number
@@ -6098,15 +6963,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_hu: function(value) {
- if (!/^HU[0-9]{8}$/.test(value)) {
+ if (/^HU[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [9, 7, 3, 1, 9, 7, 3, 1];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
@@ -6123,15 +6990,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_hr: function(value) {
- if (!/^HR[0-9]{11}$/.test(value)) {
+ if (/^HR[0-9]{11}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{11}$/.test(value)) {
return false;
}
- value = value.substr(2);
return $.fn.bootstrapValidator.helpers.mod11And10(value);
},
/**
* Validate Irish VAT number
@@ -6141,15 +7010,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_ie: function(value) {
- if (!/^IE[0-9]{1}[0-9A-Z\*\+]{1}[0-9]{5}[A-Z]{1,2}$/.test(value)) {
+ if (/^IE[0-9]{1}[0-9A-Z\*\+]{1}[0-9]{5}[A-Z]{1,2}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{1}[0-9A-Z\*\+]{1}[0-9]{5}[A-Z]{1,2}$/.test(value)) {
return false;
}
- value = value.substr(2);
var getCheckDigit = function(value) {
while (value.length < 7) {
value = '0' + value;
}
var alphabet = 'WABCDEFGHIJKLMNOPQRSTUV',
@@ -6181,11 +7052,14 @@
*
* @params {String} value VAT number
* @returns {Boolean}
*/
_is: function(value) {
- return /^IS\d{5,6}$/.test(value);
+ if (/^IS[0-9]{5,6}$/.test(value)) {
+ value = value.substr(2);
+ }
+ return /^[0-9]{5,6}$/.test(value);
},
/**
* Validate Italian VAT number, which consists of 11 digits.
* - First 7 digits are a company identifier
@@ -6198,15 +7072,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_it: function(value) {
- if (!/^IT[0-9]{11}$/.test(value)) {
+ if (/^IT[0-9]{11}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{11}$/.test(value)) {
return false;
}
- value = value.substr(2);
if (parseInt(value.substr(0, 7), 10) === 0) {
return false;
}
var lastThree = parseInt(value.substr(7, 3), 10);
@@ -6229,15 +7105,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_lt: function(value) {
- if (!/^LT([0-9]{7}1[0-9]{1}|[0-9]{10}1[0-9]{1})$/.test(value)) {
+ if (/^LT([0-9]{7}1[0-9]{1}|[0-9]{10}1[0-9]{1})$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^([0-9]{7}1[0-9]{1}|[0-9]{10}1[0-9]{1})$/.test(value)) {
return false;
}
- value = value.substr(2);
var length = value.length,
sum = 0,
i;
for (i = 0; i < length - 1; i++) {
sum += parseInt(value.charAt(i), 10) * (1 + i % 9);
@@ -6261,15 +7139,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_lu: function(value) {
- if (!/^LU[0-9]{8}$/.test(value)) {
+ if (/^LU[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
return ((parseInt(value.substr(0, 6), 10) % 89) + '' === value.substr(6, 2));
},
/**
* Validate Latvian VAT number
@@ -6279,15 +7159,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_lv: function(value) {
- if (!/^LV[0-9]{11}$/.test(value)) {
+ if (/^LV[0-9]{11}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{11}$/.test(value)) {
return false;
}
- value = value.substr(2);
var first = parseInt(value.charAt(0), 10),
sum = 0,
weight = [],
i,
length = value.length;
@@ -6330,15 +7212,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_mt: function(value) {
- if (!/^MT[0-9]{8}$/.test(value)) {
+ if (/^MT[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [3, 4, 6, 7, 8, 9, 10, 1];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
@@ -6355,14 +7239,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_nl: function(value) {
- if (!/^NL[0-9]{9}B[0-9]{2}$/.test(value)) {
+ if (/^NL[0-9]{9}B[0-9]{2}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}B[0-9]{2}$/.test(value)) {
return false;
}
- value = value.substr(2);
+
var sum = 0,
weight = [9, 8, 7, 6, 5, 4, 3, 2];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
@@ -6380,14 +7267,17 @@
* @see http://www.brreg.no/english/coordination/number.html
* @param {String} value VAT number
* @returns {Boolean}
*/
_no: function(value) {
- if (!/^NO[0-9]{9}$/.test(value)) {
+ if (/^NO[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
+
var sum = 0,
weight = [3, 2, 7, 6, 5, 4, 3, 2];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
}
@@ -6407,15 +7297,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_pl: function(value) {
- if (!/^PL[0-9]{10}$/.test(value)) {
+ if (/^PL[0-9]{10}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{10}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [6, 5, 7, 2, 3, 4, 5, 6, 7, -1];
for (var i = 0; i < 10; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
@@ -6432,15 +7324,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_pt: function(value) {
- if (!/^PT[0-9]{9}$/.test(value)) {
+ if (/^PT[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [9, 8, 7, 6, 5, 4, 3, 2];
for (var i = 0; i < 8; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
@@ -6460,14 +7354,16 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_ro: function(value) {
- if (!/^RO[1-9][0-9]{1,9}$/.test(value)) {
+ if (/^RO[1-9][0-9]{1,9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[1-9][0-9]{1,9}$/.test(value)) {
return false;
}
- value = value.substr(2);
var length = value.length,
weight = [7, 5, 3, 2, 1, 7, 5, 3, 2].slice(10 - length),
sum = 0;
for (var i = 0; i < length - 1; i++) {
@@ -6483,15 +7379,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_ru: function(value) {
- if (!/^RU([0-9]{9}|[0-9]{12})$/.test(value)) {
+ if (/^RU([0-9]{10}|[0-9]{12})$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^([0-9]{10}|[0-9]{12})$/.test(value)) {
return false;
}
- value = value.substr(2);
var i = 0;
if (value.length === 10) {
var sum = 0,
weight = [2, 4, 10, 3, 5, 9, 4, 6, 8, 0];
for (i = 0; i < 10; i++) {
@@ -6533,15 +7431,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_rs: function(value) {
- if (!/^RS[0-9]{9}$/.test(value)) {
+ if (/^RS[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{9}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 10,
temp = 0;
for (var i = 0; i < 8; i++) {
temp = (parseInt(value.charAt(i), 10) + sum) % 10;
if (temp === 0) {
@@ -6561,15 +7461,18 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_se: function(value) {
- if (!/^SE[0-9]{10}01$/.test(value)) {
+ if (/^SE[0-9]{10}01$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{10}01$/.test(value)) {
return false;
}
- value = value.substr(2, 10);
+ value = value.substr(0, 10);
return $.fn.bootstrapValidator.helpers.luhn(value);
},
/**
* Validate Slovenian VAT number
@@ -6579,15 +7482,17 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_si: function(value) {
- if (!/^SI[0-9]{8}$/.test(value)) {
+ if (/^SI[0-9]{8}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[0-9]{8}$/.test(value)) {
return false;
}
- value = value.substr(2);
var sum = 0,
weight = [8, 7, 6, 5, 4, 3, 2];
for (var i = 0; i < 7; i++) {
sum += parseInt(value.charAt(i), 10) * weight[i];
@@ -6607,28 +7512,73 @@
*
* @param {String} value VAT number
* @returns {Boolean}
*/
_sk: function(value) {
- if (!/^SK[1-9][0-9][(2-4)|(6-9)][0-9]{7}$/.test(value)) {
+ if (/^SK[1-9][0-9][(2-4)|(6-9)][0-9]{7}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[1-9][0-9][(2-4)|(6-9)][0-9]{7}$/.test(value)) {
return false;
}
- return (parseInt(value.substr(2), 10) % 11 === 0);
+ return (parseInt(value, 10) % 11 === 0);
},
/**
+ * Validate Venezuelan VAT number (RIF)
+ * Examples:
+ * - Valid: VEJ309272292, VEV242818101, VEJ000126518, VEJ000458324, J309272292, V242818101, J000126518, J000458324
+ * - Invalid: VEJ309272293, VEV242818100, J000126519, J000458323
+ *
+ * @param {String} value VAT number
+ * @returns {Boolean}
+ */
+ _ve: function(value) {
+ if (/^VE[VEJPG][0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+ if (!/^[VEJPG][0-9]{9}$/.test(value)) {
+ return false;
+ }
+
+ var types = {
+ 'V': 4,
+ 'E': 8,
+ 'J': 12,
+ 'P': 16,
+ 'G': 20
+ },
+ sum = types[value.charAt(0)],
+ weight = [3, 2, 7, 6, 5, 4, 3, 2];
+
+ for (var i = 0; i < 8; i++) {
+ sum += parseInt(value.charAt(i + 1), 10) * weight[i];
+ }
+
+ sum = 11 - sum % 11;
+ if (sum === 11 || sum === 10) {
+ sum = 0;
+ }
+ return (sum + '' === value.substr(9, 1));
+ },
+
+ /**
* Validate South African VAT number
* Examples:
* - Valid: 4012345678
* - Invalid: 40123456789, 3012345678
*
* @params {String} value VAT number
* @returns {Boolean}
*/
_za: function(value) {
- return /^ZA4\d{9}$/.test(value);
+ if (/^ZA4[0-9]{9}$/.test(value)) {
+ value = value.substr(2);
+ }
+
+ return /^4[0-9]{9}$/.test(value);
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.vin = $.extend($.fn.bootstrapValidator.i18n.vin || {}, {
@@ -6679,34 +7629,38 @@
}
};
}(window.jQuery));
;(function($) {
$.fn.bootstrapValidator.i18n.zipCode = $.extend($.fn.bootstrapValidator.i18n.zipCode || {}, {
- 'default': 'Please enter a valid zip code',
+ 'default': 'Please enter a valid postal code',
countryNotSupported: 'The country code %s is not supported',
- country: 'Please enter a valid %s',
+ country: 'Please enter a valid postal code in %s',
countries: {
- BR: 'Brazilian postal code',
- CA: 'Canadian postal code',
- DK: 'Danish postal code',
- GB: 'United Kingdom postal code',
- IT: 'Italian postal code',
- MA: 'Moroccan postal code',
- NL: 'Dutch postal code',
- SE: 'Swiss postal code',
- SG: 'Singapore postal code',
- US: 'US zip code'
+ BR: 'Brazil',
+ CA: 'Canada',
+ CZ: 'Czech Republic',
+ DK: 'Denmark',
+ GB: 'United Kingdom',
+ IT: 'Italy',
+ MA: 'Morocco',
+ NL: 'Netherlands',
+ RO: 'Romania',
+ RU: 'Russia',
+ SE: 'Sweden',
+ SG: 'Singapore',
+ SK: 'Slovakia',
+ US: 'USA'
}
});
$.fn.bootstrapValidator.validators.zipCode = {
html5Attributes: {
message: 'message',
country: 'country'
},
- COUNTRY_CODES: ['BR', 'CA', 'DK', 'GB', 'IT', 'MA', 'NL', 'SE', 'SG', 'US'],
+ COUNTRY_CODES: ['BR', 'CA', 'CZ', 'DK', 'GB', 'IT', 'MA', 'NL', 'RO', 'RU', 'SE', 'SG', 'SK', 'US'],
/**
* Return true if and only if the input value is a valid country zip code
*
* @param {BootstrapValidator} validator The validator plugin instance
@@ -6754,10 +7708,15 @@
case 'CA':
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);
break;
+ case 'CZ':
+ // Test: http://regexr.com/39hhr
+ isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
+ break;
+
case 'DK':
isValid = /^(DK(-|\s)?)?\d{4}$/i.test(value);
break;
case 'GB':
@@ -6776,18 +7735,31 @@
// http://en.wikipedia.org/wiki/Postal_codes_in_the_Netherlands
case 'NL':
isValid = /^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i.test(value);
break;
+
+ case 'RO':
+ isValid = /^(0[1-8]{1}|[1-9]{1}[0-5]{1})?[0-9]{4}$/i.test(value);
+ break;
+ case 'RU':
+ isValid = /^[0-9]{6}$/i.test(value);
+ break;
+
case 'SE':
isValid = /^(S-)?\d{3}\s?\d{2}$/i.test(value);
break;
case 'SG':
isValid = /^([0][1-9]|[1-6][0-9]|[7]([0-3]|[5-9])|[8][0-2])(\d{4})$/i.test(value);
break;
-
+
+ case 'SK':
+ // Test: http://regexr.com/39hhr
+ isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
+ break;
+
case 'US':
/* falls through */
default:
isValid = /^\d{4,5}([\-]?\d{4})?$/.test(value);
break;