I wrote this jquery plugin to do remote validations on the server. The code self explanatory. When the field blurs (event is customisable), the plugin checks to see if there is a value and sends the request.
Nothing fancy, but since I'm relatively new to JavaScript I'm sure I might have missed a few things. I think the init method is a bit long in the tooth. I am also calling removeErrors()
from a bunch of places in the method, but that might be necessary.
(function($, window, document, undefined) {
var Validator = {
init: function(options, elem) {
var self = this;
self.elem = elem;
self.$elem = $(elem);
self.url = options.url;
// Attribute is the field name we want to validate: email, username, etc...
// If the user passes it in the options, use it, if not, get it
// from the element's name attribute.
// Maybe this can be a function in the options hash?
// How do I call a function in the options hash?
if (options.attribute) {
self.attribute = options.attribute;
} else {
self.attribute = self.elem.getAttribute('name');
}
self.options = $.extend({}, $.fn.remoteValidate.options, options);
self.validate();
},
validate: function() {
var self = this;
self.$elem.on(self.options.event, function() {
// Store the current value of the field
var value = self.$elem.val();
// If the field is blank remove the errors
if (!value) {
self.removeErrors();
}
// We only want to issue a request is
// 1. The field has a value
// 2. The value has changed from the last time.
// So entering a value, blurring, then focusing and blurring
// without changing the field should trigger one request.
if (value && value !== self.attributeValue) {
self.attributeValue = value;
self.queryServer().success(function() {
self.removeErrors();
if (typeof self.options.onComplete === 'function') {
self.options.onComplete.apply(self.elem, arguments);
}
}).error(function(results) {
var errors = $.parseJSON(results.responseText).errors;
self.removeErrors();
self.buildFrag(errors);
self.displayErrors();
if (typeof self.options.onError === 'function') {
self.options.onError.apply(self.elem, arguments);
}
});
}
});
},
queryServer: function() {
var self = this;
return $.get(self.url, {
attribute: self.attribute,
format: 'json',
value: self.$elem.val()
});
},
removeErrors: function() {
var self = this;
self.$elem.siblings('.' + self.options.errorClass).remove();
},
displayErrors: function() {
var self = this;
self.$elem.after(self.errors);
},
buildFrag: function(errors) {
var self = this;
self.errors = $.map(errors, function(obj) {
return $(self.options.wrapEachWith, {
class: self.options.errorClass
}).append(obj);
});
}
};
$.fn.remoteValidate = function(options) {
return this.each(function() {
var validator = Object.create(Validator);
validator.init(options, this);
});
};
$.fn.remoteValidate.options = {
wrapEachWith: '<p></p>',
errorClass: 'error-message',
event: 'blur',
onComplete: null,
onError: null,
attribute: null
};
})(jQuery, window, document);