vendor/assets/javascripts/bootstrapValidator.js in bootstrap-validator-rails-0.0.1 vs vendor/assets/javascripts/bootstrapValidator.js in bootstrap-validator-rails-0.5.0a

- old
+ new

@@ -1,10 +1,10 @@ /*! * BootstrapValidator (http://bootstrapvalidator.com) * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3 * - * @version v0.5.0-dev, built on 2014-07-07 6:50:25 PM + * @version v0.5.0, built on 2014-07-14 4:31:02 PM * @author https://twitter.com/nghuuphuoc * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc * @license MIT */ (function($) { @@ -101,10 +101,11 @@ for (var field in this.options.fields) { this._initField(field); } this.$form.trigger($.Event('init.form.bv'), { + bv: this, options: this.options }); // Prepare the events if (this.options.onSuccess) { @@ -143,11 +144,11 @@ if ((html5AttrMap && enabled !== 'false') || (html5AttrMap !== true && ('' === enabled || 'true' === enabled))) { // Try to parse the options via attributes - validator.html5Attributes = validator.html5Attributes || { message: 'message' }; + validator.html5Attributes = $.extend({}, { message: 'message', onerror: 'onError', onsuccess: 'onSuccess' }, validator.html5Attributes); validators[v] = $.extend({}, html5AttrMap === true ? {} : html5AttrMap, validators[v]); for (html5AttrName in validator.html5Attributes) { optionName = validator.html5Attributes[html5AttrName]; optionValue = $field.attr('data-bv-' + v.toLowerCase() + '-' + html5AttrName); @@ -170,10 +171,11 @@ 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'), + onStatus: $field.attr('data-bv-onstatus'), onSuccess: $field.attr('data-bv-onsuccess'), onError: $field.attr('data-bv-onerror'), validators: validators }, emptyOptions = $.isEmptyObject(opts), // Check if the field options are set using HTML attributes @@ -270,10 +272,22 @@ .attr('data-bv-for', field) .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('success.validator.bv', function(e, data) { + $.fn.bootstrapValidator.helpers.call(that.options.fields[field].validators[validatorName].onSuccess, [e, data]); + }); + } + if (this.options.fields[field].validators[validatorName].onError) { + $field.on('error.validator.bv', 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' @@ -314,10 +328,15 @@ if (this.options.fields[field].onError) { fields.on('error.field.bv', function(e, data) { $.fn.bootstrapValidator.helpers.call(that.options.fields[field].onError, [e, data]); }); } + if (this.options.fields[field].onStatus) { + fields.on('status.field.bv', 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(' '); @@ -336,11 +355,12 @@ } }); break; } - this.$form.trigger($.Event('init.field.bv'), { + fields.trigger($.Event('init.field.bv'), { + bv: this, field: field, element: fields }); }, @@ -406,10 +426,14 @@ _submit: function() { var isValid = this.isValid(), eventType = isValid ? 'success.form.bv' : 'error.form.bv', e = $.Event(eventType); + if (isValid && this.$form.data('remote') && $.rails !== undefined) { + return; + } + this.$form.trigger(e); // Call default handler // Check if whether the submit button is clicked if (this.$submitButton) { @@ -540,17 +564,12 @@ _onSuccess: function(e) { if (e.isDefaultPrevented()) { return; } - // Call the custom submission if enabled - if (this.options.submitHandler && 'function' === typeof this.options.submitHandler) { - // If you want to submit the form inside your submit handler, please call defaultSubmit() method - this.options.submitHandler.call(this, this, this.$form); - } else { - this.disableSubmitButtons(true).defaultSubmit(); - } + // Submit the form + this.disableSubmitButtons(true).defaultSubmit(); }, /** * Called after validating a field element * @@ -559,25 +578,26 @@ */ _onFieldValidated: function($field, validatorName) { var field = $field.attr('data-bv-field'), validators = this.options.fields[field].validators, counter = {}, - numValidators = 0; - - // Trigger an event after given validator completes - if (validatorName) { - var data = { + numValidators = 0, + data = { + bv: this, field: field, element: $field, validator: validatorName }; + + // Trigger an event after given validator completes + if (validatorName) { switch ($field.data('bv.result.' + validatorName)) { case this.STATUS_INVALID: - this.$form.trigger($.Event('error.validator.bv'), data); + $field.trigger($.Event('error.validator.bv'), data); break; case this.STATUS_VALID: - this.$form.trigger($.Event('success.validator.bv'), data); + $field.trigger($.Event('success.validator.bv'), data); break; default: break; } } @@ -601,34 +621,18 @@ if (counter[this.STATUS_VALID] === numValidators) { // Remove from the list of invalid fields this.$invalidFields = this.$invalidFields.not($field); - this.$form.trigger($.Event('success.field.bv'), { - field: field, - element: $field - }); - $field.trigger($.Event('success.field.bv'), { - field: field, - element: $field, - validator: this - }); + $field.trigger($.Event('success.field.bv'), data); } // If all validators are completed and there is at least one validator which doesn't pass else if (counter[this.STATUS_NOT_VALIDATED] === 0 && counter[this.STATUS_VALIDATING] === 0 && counter[this.STATUS_INVALID] > 0) { // Add to the list of invalid fields this.$invalidFields = this.$invalidFields.add($field); - this.$form.trigger($.Event('error.field.bv'), { - field: field, - element: $field - }); - $field.trigger($.Event('error.field.bv'), { - field: field, - element: $field, - validator: this - }); + $field.trigger($.Event('error.field.bv'), data); } }, // --- // Public methods @@ -954,11 +958,12 @@ (status === this.STATUS_INVALID) ? $errors.show() : $errors.hide(); break; } // Trigger an event - this.$form.trigger($.Event('status.field.bv'), { + $field.trigger($.Event('status.field.bv'), { + bv: this, field: field, element: $field, status: status }); this._onFieldValidated($field, validatorName); @@ -1031,15 +1036,21 @@ /** * Check if all fields inside a given container are valid. * It's useful when working with a wizard-like such as tab, collapse * - * @param {jQuery} $container The container element + * @param {String|jQuery} container The container selector or element * @returns {Boolean} */ - isValidContainer: function($container) { - var that = this, map = {}; + isValidContainer: function(container) { + var that = this, + map = {}, + $container = ('string' === typeof container) ? $(container) : container; + if ($container.length === 0) { + return true; + } + $container.find('[data-bv-field]').each(function() { var $field = $(this), field = $field.attr('data-bv-field'); if (!that._isExcluded($field) && !map[field]) { map[field] = $field; @@ -1067,12 +1078,10 @@ }, /** * Submit the form using default submission. * It also does not perform any validations when submitting the form - * - * It might be used when you want to submit the form right inside the submitHandler() */ defaultSubmit: function() { if (this.$submitButton) { // Create hidden input to send the submit buttons $('<input/>') @@ -1156,10 +1165,40 @@ 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 @@ -1391,13 +1430,14 @@ return this; }, /** - * Some other validators have option which its value is dynamic. - * For example, the zipCode validator which country is set by a select element. + * Some validators have option which its value is dynamic. + * For example, the zipCode validator has the country option which might be changed dynamically by a select element. * + * @param {jQuery|String} field The field name or element * @param {String|Function} option The option which can be determined by: * - a string * - name of field which defines the value * - name of function which returns the value * - a function returns the value @@ -1407,14 +1447,13 @@ * // value is the value of field * // validator is the BootstrapValidator instance * // $field is the field element * } * - * @param {jQuery|String} field The field name or element * @returns {String} */ - getDynamicOption: function(option, field) { + getDynamicOption: function(field, option) { var $field = ('string' === typeof field) ? this.getFieldElements(field) : field, value = $field.val(); // Option can be determined by // ... a function @@ -1593,19 +1632,10 @@ // The submit buttons selector // These buttons will be disabled to prevent the valid form from multiple submissions submitButtons: '[type="submit"]', - // The custom submit handler - // It will prevent the form from the default submission - // - // submitHandler: function(validator, form) { - // - validator is the BootstrapValidator instance - // - form is the jQuery object presenting the current form - // } - submitHandler: null, - // Live validating option // Can be one of 3 values: // - enabled: The plugin validates fields as soon as they are changed // - disabled: Disable the live validating. The error messages are only shown after the form is submitted // - submitted: The live validating is enabled after the form is submitted @@ -1688,11 +1718,11 @@ day = parseInt(day, 10); month = parseInt(month, 10); year = parseInt(year, 10); - if (year < 1000 || year > 9999 || month === 0 || month > 12) { + if (year < 1000 || year > 9999 || month <= 0 || month > 12) { return false; } var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Update the number of days in Feb of leap year if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) { @@ -1849,12 +1879,12 @@ var value = $field.val(); if (value === '') { return true; } - var min = $.isNumeric(options.min) ? options.min : validator.getDynamicOption(options.min, $field), - max = $.isNumeric(options.max) ? options.max : validator.getDynamicOption(options.max, $field); + var min = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min), + max = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max); value = parseFloat(value); return (options.inclusive === true || options.inclusive === undefined) ? { valid: value >= min && value <= max, @@ -1943,12 +1973,12 @@ */ validate: function(validator, $field, options) { var numChoices = $field.is('select') ? validator.getFieldElements($field.attr('data-bv-field')).find('option').filter(':selected').length : validator.getFieldElements($field.attr('data-bv-field')).filter(':checked').length, - min = options.min ? ($.isNumeric(options.min) ? options.min : validator.getDynamicOption(options.min, $field)) : null, - max = options.max ? ($.isNumeric(options.max) ? options.max : validator.getDynamicOption(options.max, $field)) : null, + min = options.min ? ($.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min)) : null, + max = options.max ? ($.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max)) : null, isValid = true, message = options.message || $.fn.bootstrapValidator.i18n.choice['default']; if ((min && numChoices < parseInt(min, 10)) || (max && numChoices > parseInt(max, 10))) { isValid = false; @@ -2309,14 +2339,22 @@ } // Determine the date date = date.split(separator); dateFormat = dateFormat.split(separator); + if (date.length !== dateFormat.length) { + return false; + } + var year = date[$.inArray('YYYY', dateFormat)], month = date[$.inArray('MM', dateFormat)], day = date[$.inArray('DD', dateFormat)]; + if (!year || !month || !day) { + return false; + } + // Determine the time var minutes = null, hours = null, seconds = null; if (timeFormat) { timeFormat = timeFormat.split(':'); time = time.split(':'); @@ -2608,11 +2646,11 @@ var value = $field.val(); if (value === '') { return true; } - var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption(options.value, $field); + var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value); value = parseFloat(value); return (options.inclusive === true || options.inclusive === undefined) ? { valid: value >= compareTo, @@ -2919,11 +2957,11 @@ var country = options.country; if (!country) { country = value.substr(0, 2); } else if (typeof country !== 'string' || !this.REGEX[country]) { // Determine the country code - country = validator.getDynamicOption(country, $field); + country = validator.getDynamicOption($field, country); } if (!this.REGEX[country]) { return { valid: false, @@ -3031,11 +3069,11 @@ var country = options.country; if (!country) { country = value.substr(0, 2); } else if (typeof country !== 'string' || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) { // Determine the country code - country = validator.getDynamicOption(country, $field); + country = validator.getDynamicOption($field, country); } if ($.inArray(country, this.COUNTRY_CODES) === -1) { return { valid: false, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.id.countryNotSupported, country) }; } @@ -3254,14 +3292,14 @@ * @see https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html for samples * @param {String} value The ID * @returns {Boolean} */ _cl: function(value) { - if (!/^\d{7,8}[-]{0,1}[0-9K]$/.test(value)) { + if (!/^\d{7,8}[-]{0,1}[0-9K]$/i.test(value)) { return false; } - value = value.replace(/\D/g, ''); + value = value.replace(/\-/g, ''); while (value.length < 9) { value = '0' + value; } var sum = 0, weight = [3, 2, 7, 6, 5, 4, 3, 2]; @@ -3272,11 +3310,11 @@ if (sum === 11) { sum = 0; } else if (sum === 10) { sum = 'K'; } - return sum + '' === value.charAt(8); + return sum + '' === value.charAt(8).toUpperCase(); }, /** * Validate Czech national identification number (RC) * Examples: @@ -3865,11 +3903,11 @@ 'default': 'Please enter a valid number' }); $.fn.bootstrapValidator.validators.integer = { enableByHtml5: function($field) { - return ('number' === $field.attr('type')); + return ('number' === $field.attr('type')) && ($field.attr('step') === undefined || $field.attr('step') % 1 === 0); }, /** * Return true if the input value is an integer * @@ -4230,11 +4268,11 @@ var value = $field.val(); if (value === '') { return true; } - var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption(options.value, $field); + var compareTo = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value); value = parseFloat(value); return (options.inclusive === true || options.inclusive === undefined) ? { valid: value <= compareTo, @@ -4313,10 +4351,14 @@ html5Attributes: { message: 'message', separator: 'separator' }, + enableByHtml5: function($field) { + return ('number' === $field.attr('type')) && ($field.attr('step') !== undefined) && ($field.attr('step') % 1 !== 0); + }, + /** * Validate decimal number * * @param {BootstrapValidator} validator The validator plugin instance * @param {jQuery} $field Field element @@ -4383,11 +4425,11 @@ } var country = options.country; if (typeof country !== 'string' || $.inArray(country, this.COUNTRY_CODES) === -1) { // Try to determine the country - country = validator.getDynamicOption(country, $field); + country = validator.getDynamicOption($field, country); } if (!country || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) { return { valid: false, @@ -4827,12 +4869,12 @@ var value = $field.val(); if (value === '') { return true; } - var min = $.isNumeric(options.min) ? options.min : validator.getDynamicOption(options.min, $field), - max = $.isNumeric(options.max) ? options.max : validator.getDynamicOption(options.max, $field), + var min = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min), + max = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max), length = value.length, isValid = true, message = options.message || $.fn.bootstrapValidator.i18n.stringLength['default']; if ((min && length < parseInt(min, 10)) || (max && length > parseInt(max, 10))) { @@ -5084,11 +5126,11 @@ var country = options.country; if (!country) { country = value.substr(0, 2); } else if (typeof country !== 'string' || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) { // Determine the country code - country = validator.getDynamicOption(country, $field); + country = validator.getDynamicOption($field, country); } if ($.inArray(country, this.COUNTRY_CODES) === -1) { return { valid: false, @@ -6341,21 +6383,21 @@ } var country = options.country; if (typeof country !== 'string' || $.inArray(country, this.COUNTRY_CODES) === -1) { // Try to determine the country - country = validator.getDynamicOption(country, $field); + country = validator.getDynamicOption($field, country); } if (!country || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) { return { valid: false, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.zipCode.countryNotSupported, country) }; } var isValid = false; country = country.toUpperCase(); switch (country) { 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|X|Y){1}\s?[0-9]{1}(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|X|Y){1}[0-9]{1}$/i.test(value); + 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 'DK': isValid = /^(DK(-|\s)?)?\d{4}$/i.test(value); break;