After using a few validation libraries I finally decided to roll my own implementation, since none of the libraries behaved the way I wanted. The code below works fine, but I think it’s not very idiomatic. The function body is huge and should probably be refactored into smaller chunks.
I am sure there are many ways to improve my code, but I am asking for specific advice on how to break up the large function into smaller functions, so that the code is easier to understand. Obviously I want to add a lot more validation functions, and I don’t want to create a bunch of spaghetti.
The validation should happen on blur of an element. By inserting and removing divs the user is notified of the problem.
The validation function:
(function($) {
$.fn.extend({
live_validate: function() {
return this.each(function() {
var inputs = $('input', $(this));
inputs.blur(function() {
var el = $(this);
el.siblings('div.feedback').remove();
if(el.hasAttr('required') && el.val() == '') {
el.after('<div class="feedback feedback-error">must be present</div>');
return;
}
if(el.hasAttr('minlength') && el.val().length < el.attr('minlength')) {
el.after('<div class="feedback feedback-error">is too small</div>');
return;
}
// no validation returned; all good.
el.filter(":visible").after('<div class="feedback feedback-ok"></div>');
});
});
}
});
})(jQuery);
This is a quick helper I made to check if an attribute is present. I need to know if the attribute is present at all. Is there a better way to do this?
$.fn.hasAttr = function(name) {
return (this.attr(name) !== undefined && this.attr(name) !== false);
};
Finally, call the validator on the form I want.
$(document).ready(function() {
$("form.new_user").live_validate();
}
I would separate each validator in it’s own function, separating each logic in another function.
What I did here was to encapsulate each validation in it’s own funcion. It always receives de element and returns true if it’s valid or a string with the error if it’s invalid. I also added an enabledValidators to be able to pass which validators you want to run (you could remove this and execute all the validators always if you want, or only use all the validators if nothing was passed). So you would call it like this: