vendor/assets/javascripts/formvalidation.js in formvalidation-rails-0.6.1.2 vs vendor/assets/javascripts/formvalidation.js in formvalidation-rails-0.6.3

- old
+ new

@@ -1,10 +1,10 @@ /*! * FormValidation (http://formvalidation.io) * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks * - * @version v0.6.1, built on 2015-02-24 10:14:10 PM + * @version v0.6.2-dev, built on 2015-03-13 8:15:45 AM * @author https://twitter.com/nghuuphuoc * @copyright (c) 2013 - 2015 Nguyen Huu Phuoc * @license http://formvalidation.io/license/ */ // Register the namespace @@ -49,10 +49,11 @@ // Validating status this.STATUS_NOT_VALIDATED = 'NOT_VALIDATED'; this.STATUS_VALIDATING = 'VALIDATING'; this.STATUS_INVALID = 'INVALID'; this.STATUS_VALID = 'VALID'; + this.STATUS_IGNORED = 'IGNORED'; // Determine the event that is fired when user change the field value // Most modern browsers supports input event except IE 7, 8. // IE 9 supports input event but the event is still not fired if I press the backspace key. // Get IE version @@ -127,11 +128,12 @@ fieldError: this.$form.attr('data-' + ns + '-events-field-error'), fieldSuccess: this.$form.attr('data-' + ns + '-events-field-success'), fieldStatus: this.$form.attr('data-' + ns + '-events-field-status'), localeChanged: this.$form.attr('data-' + ns + '-events-locale-changed'), validatorError: this.$form.attr('data-' + ns + '-events-validator-error'), - validatorSuccess: this.$form.attr('data-' + ns + '-events-validator-success') + validatorSuccess: this.$form.attr('data-' + ns + '-events-validator-success'), + validatorIgnored: this.$form.attr('data-' + ns + '-events-validator-ignored') }, excluded: this.$form.attr('data-' + ns + '-excluded'), icon: { valid: this.$form.attr('data-' + ns + '-icon-valid') || this.$form.attr('data-' + ns + '-feedbackicons-valid'), // Support backward invalid: this.$form.attr('data-' + ns + '-icon-invalid') || this.$form.attr('data-' + ns + '-feedbackicons-invalid'), // Support backward @@ -369,11 +371,10 @@ FormValidation.Validator[validatorName].init(this, $field, this.options.fields[field].validators[validatorName]); } } // Prepare the feedback icons - // Available from Bootstrap 3.1 (http://getbootstrap.com/css/#forms-control-validation) if (this.options.fields[field].icon !== false && this.options.fields[field].icon !== 'false' && this.options.icon && this.options.icon.valid && this.options.icon.invalid && this.options.icon.validating && (!updateAll || i === total - 1)) { @@ -488,10 +489,17 @@ case (!!field && this.options.fields && this.options.fields[field] && (this.options.fields[field].excluded === 'false' || this.options.fields[field].excluded === false)): case (excludedAttr === 'false'): return false; + case (!!field && this.options.fields && this.options.fields[field] && 'function' === typeof this.options.fields[field].excluded): + return this.options.fields[field].excluded.call(this, $field, this); + + case (!!field && this.options.fields && this.options.fields[field] && 'string' === typeof this.options.fields[field].excluded): + case (excludedAttr): + return FormValidation.Helper.call(this.options.fields[field].excluded, [$field, this]); + default: if (this.options.excluded) { // Convert to array first if ('string' === typeof this.options.excluded) { this.options.excluded = $.map(this.options.excluded.split(','), function(item) { @@ -812,19 +820,23 @@ $field.trigger($.Event(this.options.events.validatorError), data); break; case this.STATUS_VALID: $field.trigger($.Event(this.options.events.validatorSuccess), data); break; + case this.STATUS_IGNORED: + $field.trigger($.Event(this.options.events.validatorIgnored), data); + break; default: break; } } counter[this.STATUS_NOT_VALIDATED] = 0; counter[this.STATUS_VALIDATING] = 0; counter[this.STATUS_INVALID] = 0; counter[this.STATUS_VALID] = 0; + counter[this.STATUS_IGNORED] = 0; for (var v in validators) { if (validators[v].enabled === false) { continue; } @@ -834,11 +846,12 @@ if (result) { counter[result]++; } } - if (counter[this.STATUS_VALID] === numValidators) { + // The sum of valid fields now also include ignored fields + if (counter[this.STATUS_VALID] + counter[this.STATUS_IGNORED] === numValidators) { // Remove from the list of invalid fields this.$invalidFields = this.$invalidFields.not($field); $field.trigger($.Event(this.options.events.fieldSuccess), data); } @@ -1060,11 +1073,11 @@ /** * Get the validating result of field * * @param {String|jQuery} field The field name or field element * @param {String} validatorName The validator name - * @returns {String} The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID' or 'VALID' + * @returns {String} The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED' */ getStatus: function(field, validatorName) { var ns = this._namespace; switch (typeof field) { case 'object': @@ -1302,17 +1315,19 @@ $fields.each(function() { $(this) .data(ns + '.messages') .find('.' + that.options.err.clazz + '[data-' + ns + '-validator="' + validator + '"][data-' + ns + '-for="' + field + '"]').html(message); }); + + return this; }, /** * Update all validating results of field * * @param {String|jQuery} field The field name or field element - * @param {String} status The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID' or 'VALID' + * @param {String} status The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED' * @param {String} [validatorName] The validator name. If null, the method updates validity result for all validators * @returns {FormValidation.Base} */ updateStatus: function(field, status, validatorName) { var ns = this._namespace, @@ -1357,11 +1372,13 @@ $icon = $field.data(ns + '.icon'), // Support backward container = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container)) ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this) : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container), - isValidField = null; + isValidField = null, + isValidating, + isNotValidated; // Update status if (validatorName) { $field.data(ns + '.result.' + validatorName, status); } else { @@ -1393,39 +1410,50 @@ $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.validating).addClass(this.options.icon.invalid).show(); } break; case this.STATUS_VALID: - var isValidating = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING +'"]').length > 0), - isNotValidated = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED +'"]').length > 0); + case this.STATUS_IGNORED: // Treat ignored fields like they are valid with some specialties + isValidating = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING +'"]').length > 0); + isNotValidated = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED +'"]').length > 0); // If the field is valid (passes all validators) - isValidField = (isValidating || isNotValidated) // There are some validators that have not done - ? null - : ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALID +'"]').length === $allErrors.length); // All validators are completed + isValidField = (isValidating || isNotValidated) // There are some validators that have not done + ? null + : ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALID +'"]').length + + $allErrors.filter('[data-' + ns + '-result="' + this.STATUS_IGNORED +'"]').length === $allErrors.length); // All validators are completed $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid); if (isValidField === true) { this.disableSubmitButtons(this.isValid() === false); - $field.addClass(this.options.control.valid); + if (status === this.STATUS_VALID) { + $field.addClass(this.options.control.valid); + } } else if (isValidField === false) { this.disableSubmitButtons(true); - $field.addClass(this.options.control.invalid); + if (status === this.STATUS_VALID) { + $field.addClass(this.options.control.invalid); + } } if ($icon) { - $icon - .removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).removeClass(this.options.icon.valid) - .addClass(isValidField === null ? '' : (isValidField ? this.options.icon.valid - : (isValidating ? this.options.icon.validating : this.options.icon.invalid))) - .show(); + $icon.removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).removeClass(this.options.icon.valid); + if (status === this.STATUS_VALID) { + $icon.addClass(isValidField === null + ? '' : (isValidField ? this.options.icon.valid : (isValidating ? this.options.icon.validating : this.options.icon.invalid))) + .show(); + } } var isValidContainer = this.isValidContainer($parent); if (isValidContainer !== null) { - $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid).addClass(isValidContainer ? this.options.row.valid : this.options.row.invalid); + $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid); + + if (status === this.STATUS_VALID || $allErrors.length > 1) { + $parent.addClass(isValidContainer ? this.options.row.valid : this.options.row.invalid); + } } break; case this.STATUS_NOT_VALIDATED: /* falls through */ @@ -1558,28 +1586,32 @@ $f.removeData(ns + '.dfs.' + v).data(ns + '.response.' + v, response); if (response.message) { that.updateMessage($f, v, response.message); } - that.updateStatus(updateAll ? $f.attr('data-' + ns + '-field') : $f, response.valid ? that.STATUS_VALID : that.STATUS_INVALID, v); + that.updateStatus(updateAll ? $f.attr('data-' + ns + '-field') : $f, + response.valid === true ? that.STATUS_VALID : (response.valid === false ? that.STATUS_INVALID : that.STATUS_IGNORED), + v); 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) { + } else if (response.valid === false && !verbose) { stop = true; } }); } - // ... or object { valid: true/false, message: 'dynamic message', otherKey: value, ... } + // ... or object { valid: true/false/null, message: 'dynamic message', otherKey: value, ... } else if ('object' === typeof validateResult && validateResult.valid !== undefined) { $field.data(ns + '.response.' + validatorName, validateResult); if (validateResult.message) { 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) { + this.updateStatus(updateAll ? field : $field, + validateResult.valid === true ? this.STATUS_VALID : (validateResult.valid === false ? this.STATUS_INVALID : this.STATUS_IGNORED), + validatorName); + if (validateResult.valid === false && !verbose) { break; } } // ... or a boolean value else if ('boolean' === typeof validateResult) { @@ -1587,10 +1619,16 @@ this.updateStatus(updateAll ? field : $field, validateResult ? this.STATUS_VALID : this.STATUS_INVALID, validatorName); if (!validateResult && !verbose) { break; } } + // ... or null/undefined + // to indicate that the field should be ignored for current validation + else if (null === validateResult || undefined === validateResult) { + $field.data(ns + '.response.' + validatorName, validateResult); + this.updateStatus(updateAll ? field : $field, this.STATUS_IGNORED, validatorName); + } } } return this; }, @@ -1630,11 +1668,11 @@ for (var i = 0; i < total; i++) { var $field = fields.eq(i); // Try to parse the options from HTML attributes var opts = this._parseOptions($field); - opts = (opts === null) ? options : $.extend(true, options, opts); + opts = (opts === null) ? options : $.extend(true, opts, options); this.options.fields[field] = $.extend(true, this.options.fields[field], opts); // Update the cache this._cacheFields[field] = this._cacheFields[field] ? this._cacheFields[field].add($field) : $field; @@ -1988,18 +2026,18 @@ $fields.eq(i).removeData(ns + '.dfs.' + validator); } } } - // Mark field as not validated yet - this.updateStatus(field, this.STATUS_NOT_VALIDATED); - if (resetValue) { var type = $fields.attr('type'); ('radio' === type || 'checkbox' === type) ? $fields.prop('checked', false).removeAttr('selected') : $fields.val(''); } + // Mark field as not validated yet + this.updateStatus(field, this.STATUS_NOT_VALIDATED); + return this; }, /** * Reset the form @@ -2161,11 +2199,12 @@ fieldError: 'err.field.fv', fieldSuccess: 'success.field.fv', fieldStatus: 'status.field.fv', localeChanged: 'changed.locale.fv', validatorError: 'err.validator.fv', - validatorSuccess: 'success.validator.fv' + validatorSuccess: 'success.validator.fv', + validatorIgnored: 'ignored.validator.fv' }, // Indicate fields which won't be validated // By default, the plugin will not validate the following kind of fields: // - disabled @@ -2637,11 +2676,11 @@ dfd = new $.Deferred(), result = { valid: true }; if (options.callback) { var response = FormValidation.Helper.call(options.callback, [value, validator, $field]); - result = ('boolean' === typeof response) ? { valid: response } : response; + result = ('boolean' === typeof response || null === response) ? { valid: response } : response; } dfd.resolve($field, 'callback', result); return dfd; } @@ -3265,11 +3304,13 @@ } // Determine the separator var separator = options.separator; if (!separator) { - separator = (date.indexOf('/') !== -1) ? '/' : ((date.indexOf('-') !== -1) ? '-' : null); + separator = (date.indexOf('/') !== -1) + ? '/' + : ((date.indexOf('-') !== -1) ? '-' : ((date.indexOf('.') !== -1) ? '.' : null)); } if (separator === null || date.indexOf(separator) === -1) { return { valid: false, message: message @@ -4584,11 +4625,11 @@ * @returns {Boolean} */ _br: function(value) { value = value.replace(/\D/g, ''); - if (/^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) { + if (!/^\d{11}$/.test(value) || /^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) { return false; } var d1 = 0; for (var i = 0; i < 9; i++) { @@ -6997,11 +7038,13 @@ function runCallback() { var xhr = $.ajax(ajaxOptions); xhr .success(function(response) { - response.valid = response[validKey] === true || response[validKey] === 'true'; + response.valid = (response[validKey] === true || response[validKey] === 'true') + ? true + : (response[validKey] === false || response[validKey] === 'false' ? false : null); dfd.resolve($field, 'remote', response); }) .error(function(response) { dfd.resolve($field, 'remote', { valid: false @@ -8203,9 +8246,12 @@ temp = Math.floor(temp / 10) + temp % 10; } sum += temp; } sum = 10 - sum % 10; + if (sum === 10) { + sum = 0; + } return (sum + '' === value.substr(8, 1) || 'JABCDEFGHI'[sum] === value.substr(8, 1)); } return false; };