Contenido

Validar formularios con jQuery

25 Jun

+ 17

Hace unas semanas tuve que desarrollar una función que me permitiera validar formularios mediante Javascript de una forma fácil y rápida. Tenía que ser con jQuery por que es el framework que estamos usando ahora en el trabajo. Una de las premisas era que debido a la aplicación y a la tecnología, necesitaba que fuera lo más flexible posible, por ese motivo opté por el siguiente código:

El código

//Filtros
var filters = {
    requerido: function(el) {return ($(el).val() != '' && $(el).val() != -1);},
    email: function(el) {return /^[A-Za-z][A-Za-z0-9_]*@[A-Za-z0-9_]+\.[A-Za-z0-9_.]+[A-za-z]$/.test($(el).val());},
    telefono: function(el){return /^[0-9]*$/.test($(el).val());}};
// Extensiones
$.extend({
	stop: function(e){
        if (e.preventDefault) e.preventDefault();
        if (e.stopPropagation) e.stopPropagation();
    }
});
// Código
$(document).ready(function(){
	$("form.validable").bind("submit", function(e){
		if (typeof filters == 'undefined') return;
	    $(this).find("input, textarea, select").each(function(x,el){
	        if ($(el).attr("className") != 'undefined') {
	        $.each(new String($(el).attr("className")).split(" "), function(x, klass){
	            if ($.isFunction(filters[klass]))
	                if (!filters[klass](el))  $(el).addClass("error");
	        });
	        }
	    });
		if ($(this).find(".error").size() > 0) {
			$.stop(e || window.event);
			return false;
		}
	    return true;
	});
});
	

Explicación

Si no fijamos en el código podemos ver que este script, será ejecutado en cuando el contenido de la página esté completamente cargado, esto lo conseguimos gracias a $(document).ready(); que jQuery nos ofrece.

Una vez cargado el contenido, se encargará de recorrar todos los elementos y buscará todos los elementos <form class="validable">, a los que le añadirá un listener que será ejecutado en el momento que el formulario ejecute el método submit().

En ese momento, el script recoge todos los element <input />, <textarea /> y <select /> del formulario y revisa las clases de cada elemento. Dependiendo de la clase y si está está definida en el objeto filters, realizará una comprobación u otra.

El objeto filters, se compone de una serie de métodos que serán lanzados para validar cada uno de los elementos, por ejemplo:

//HTML
<input type="text" name="prueba" value="" class="requerido email noanieto" />

//Javascript (Filtros)
var filters = {
       requerido: function(el) {return ($(el).val() != '' && $(el).val() != -1);},
       email: function(el) {return /^[A-Za-z][A-Za-z0-9_]*@[A-Za-z0-9_]+\.[A-Za-z0-9_.]+[A-za-z]$/.test($(el).val());},
       noanieto: function(el){return !"anieto".indexOf($(el).val());}
}

Como podemos ver el elemento <input />, le estamos indicando que es del tipo requerido, email y noanieto. Validaciones que definimos en el objeto filters. En caso de no existir una de las clases indicadas en el elemento <input /> (o cualquier otro), esta será omitida.

Si el elemento no cumple una de las condiciones, añadiremos una clase más al elemento (class="error") y pararemos la ejecución del submit().

Demo

He montado una pequeña demo para verlo funcionar. La podeis probar aqui.

Aclaraciones

Está claro que se trata de una validación Javascript y que su única función es mejorar la experiencia del usuario evitando que llegue a submitar una página con datos erroneos, para hacer las cosas bien, la página receptora, debería hacer la misma comprobación y devolver a la página anterior en caso de error, así los usuarios que no tengan la capacidad de ejecutar javascript, tendrán un resultado igual a los que sí, aunque tengan que esperar a la carga de la página.

Versión para MooTools

Epplestun, me pasa una adaptación del script para MooTools. Muchas gracias!!!

$(document).addEvent('domready', function() {
       $(document.body).getElements('form.validable').addEvent('submit', function(e) {
               if (typeof filters == 'undefined')
                       return;

          this.getElements("input, textarea, select").each(function(el) {
               if (el.getProperty("class").length) {
                       el.removeClass("error");
                               el.getProperty("class").split(" ").each(function(filtro) {
                                       if (!filters[filtro](el))
                                               el.addClass("error");
                               });
               }
          });

          this.getChildren().each(function(el) {
               if(el.hasClass("error")) {
                               e = new Event(e);
                               e.stop();
                       return false;
               }
          });

          return true;
       });

Mm… algo así venia buscando hace un tiempo para una web. Quería evitar tardar demasiado con el formulario.
Me gustaría que me explicases el filtro

noanieto: function(el){return !”anieto”.indexOf($(el).val());}

gracias, como siempre

@Manuchis: Te explico, devuelve false en caso de encontrar la palabra “anieto” dentro del value del elemento.

Existe un plugin, JQuery.validate(), que es bastante configurable (todos los validators son externos) y potente a la vez que simple.

Como siempre excelente el tutorial. Muchas gracias

@Blaxter: Si, lo conozco aunque no lo he usado. Cuando lo vi me pareció bastante poco flexible y complicado para que lo use gente que no controla de Javascript.

Excelente, sencillamente practico y flexible, ahora que estoy empezando a utilizar jQuery me sirve para dar mis primeros pinitos!! Gracias!!

Muy interesante. Lo que no me ha gustado es eso de “submitar”, podrías haber usado enviar.

Muy bueno la verdad, jeje y para los que les den a MooTools como yo dejo aquí la versión del validable.js en MooTools :-), en los filtros en lugar de usar $(el).val() se ha de utilizar $(el).value y listo, funciona :-D

$(document).addEvent('domready', function() {
	$(document.body).getElements('form.validable').addEvent('submit', function(e) {
		if (typeof filters == 'undefined')
			return;

	   this.getElements("input, textarea, select").each(function(el) {
	   	if (el.getProperty("class").length) {
	   		el.removeClass("error");
				el.getProperty("class").split(" ").each(function(filtro) {
					if (!filters[filtro](el))
						el.addClass("error");
				});
	   	}
	   });

	   this.getChildren().each(function(el) {
	   	if(el.hasClass("error")) {
				e = new Event(e);
				e.stop();
	   		return false;
	   	}
	   });

	   return true;
	});
});

Excelente, super simple y limpio.

Gracias.

Fácil, rápido y para toda la familia, jejejeje.

Me encanta tu blog. Felicidades!!!

excelente, me encanta el funcionamiento, yo usaba algo parecido usando expresion regulares en el atributo rel http://refactormycode.com/codes/149-simple-form-validator-with-regex (igual te sirve para ampliar el tuyo) permitiendo engachar una función para casos en los que no me servian expresiones regulares.

¿Se puede usar/extender este script libremente?

Un saludo

@jdeveloper: Me gusta la idea, le echaré un vistazo.

Puedes usar/extenderlo lo que tu veas ;)
Gracias

Andrés gracias por poner el codigo legible jejeje :-)

Excelente validador, y excelente blog :)
He estado haciendo pruebas con él y he visto un error, que a mi al menos me salía, en la línea:

$.stop(e || window.event);

Lo he solucionado poniéndolo de la siguiente forma:

$(this).stop(e || window.event);

Saludos,

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.


Cerrar
Enviar por Correo