jq-idealform-test/js/private.js
2014-06-10 08:05:36 -04:00

211 lines
5.4 KiB
JavaScript

/**
* 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(handleError, handleStyle) {
var self = this;
this.$inputs.each(function(){ self._validate(this, handleError, handleStyle); });
}
};