123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /**
- * Private methods
- */
- module.exports = {
- _init: function() {
- var self = this;
- this.$form = $(this.el);
- this.$fields = $();
- this.$inputs = $();
- this._extend($.idealforms.extensions);
- this._i18n();
- this._inject('_init');
- this._addMarkupRules();
- this.addRules(this.opts.rules || {});
- this.$form.submit(function(e) {
- self._validateAll(true);
- self.focusFirstInvalid();
- self.opts.onSubmit.call(self, self.getInvalid().length, e);
- });
- if (! this.opts.silentLoad) {
- // 1ms timeout to make sure error shows up
- setTimeout($.proxy(this.focusFirstInvalid, this), 1);
- }
- },
- _addMarkupRules: function() {
- var rules = {};
- this.$form.find('input, select, textarea').each(function() {
- var rule = $(this).data('idealforms-rules');
- if (rule && ! rules[this.name]) rules[this.name] = rule;
- });
- this.addRules(rules);
- },
- _i18n: function() {
- var self = this;
- $.each($.idealforms.i18n, function(locale, lang) {
- var errors = lang.errors
- , options = {};
- delete lang.errors;
- for (var ext in lang) options[ext] = { i18n: lang[ext] };
- $.extend($.idealforms.errors, errors);
- $.extend(true, self.opts, options);
- });
- },
- _buildField: function(input) {
- var self = this
- , $field = this._getField(input)
- , $icon;
- $icon = $(this.opts.iconHtml, {
- class: this.opts.iconClass,
- click: function(){ $(input).focus() }
- });
- if (! this.$fields.filter($field).length) {
- this.$fields = this.$fields.add($field);
- if (this.opts.iconHtml) $field.append($icon);
- $field.addClass('idealforms-field idealforms-field-'+ input.type);
- }
- this._addEvents(input);
- this._inject('_buildField', input);
- },
- _addEvents: function(input) {
- var self = this
- , $field = this._getField(input);
- $(input)
- .on('change keyup', function(e) {
- if (e.which == 9 || e.which == 16) return;
- self._validate(this, true, true);
- })
- .focus(function() {
- if (! self.isValid(this.name)) {
- $field.find(self.opts.error).show();
- }
- })
- .blur(function() {
- $field.find(self.opts.error).hide();
- });
- },
- _isRequired: function(input) {
- // We assume non-text inputs with rules are required
- if ($(input).is(':checkbox, :radio, select')) return true;
- return this.opts.rules[input.name].indexOf('required') > -1;
- },
- _getRelated: function(input) {
- return this._getField(input).find('[name="'+ input.name +'"]');
- },
- _getField: function(input) {
- return $(input).closest(this.opts.field);
- },
- _getFirstInvalid: function() {
- return this.getInvalid().first().find('input:first, textarea, select');
- },
- _handleError: function(input, error, valid) {
- valid = valid || this.isValid(input.name);
- var $error = this._getField(input).find(this.opts.error);
- this.$form.find(this.opts.error).hide();
- if (error) $error.text(error);
- $error.toggle(!valid);
- },
- _handleStyle: function(input, valid) {
- valid = valid || this.isValid(input.name);
- this._getField(input)
- .removeClass(this.opts.validClass +' '+ this.opts.invalidClass)
- .addClass(valid ? this.opts.validClass : this.opts.invalidClass)
- .find('.'+ this.opts.iconClass).show();
- },
- _fresh: function(input) {
- this._getField(input)
- .removeClass(this.opts.validClass +' '+ this.opts.invalidClass)
- .find(this.opts.error).hide()
- .end()
- .find('.'+ this.opts.iconClass).toggle(this._isRequired(input));
- },
- _validate: function(input, handleError, handleStyle) {
- var self = this
- , $field = this._getField(input)
- , userRules = this.opts.rules[input.name].split($.idealforms.ruleSeparator)
- , oldValue = $field.data('idealforms-value')
- , valid = true
- , rule;
- // Don't validate input if value hasn't changed
- if (! $(input).is(':checkbox, :radio') && oldValue == input.value) {
- return $field.data('idealforms-valid');
- }
- $field.data('idealforms-value', input.value);
- // Non-required input with empty value must pass validation
- if (! input.value && ! this._isRequired(input)) {
- $field.removeData('idealforms-valid');
- this._fresh(input);
- // Inputs with value or required
- } else {
- $.each(userRules, function(i, userRule) {
- userRule = userRule.split($.idealforms.argSeparator);
- rule = userRule[0];
- var theRule = $.idealforms.rules[rule]
- , args = userRule.slice(1)
- , error;
- error = $.idealforms._format.apply(null, [
- $.idealforms._getKey('errors.'+ input.name +'.'+ rule, self.opts) ||
- $.idealforms.errors[rule]
- ].concat(args));
- valid = typeof theRule == 'function'
- ? theRule.apply(self, [input, input.value].concat(args))
- : theRule.test(input.value);
- $field.data('idealforms-valid', valid);
- if (handleError) self._handleError(input, error, valid);
- if (handleStyle) self._handleStyle(input, valid);
- self.opts.onValidate.call(self, input, rule, valid);
- return valid;
- });
- }
- this._inject('_validate', input, rule, valid);
- return valid;
- },
- _validateAll: function(handleStyle, handleError) {
- var self = this;
- this.$inputs.each(function(){ self._validate(this, handleStyle, handleError); });
- }
- };
|