Ejemplo de validaciones con jQuery
Como ya he dicho en la introducción queremos conseguir una validación de formulario en tiempo real, es decir cada vez que un campo del formulario pierda el foco, automáticamente comprobaremos que el campo modificado es correcto, además comprobaremos que todos los campos que preceden a este no se encuentran vacios y que la información es correcta. Con esto mejoraremos la experiencia de usuario ya que avisamos en el mismo momento de cada uno de los errores que está cometiendo al introducir los datos en los campos del formulario y estaremos evitando el tener que realizar varios envíos del form ya que se produjeron fallos en la validación de campos obligatorios.
Dentro de un formulario podemos fijar una serie de campos que sean de tipo obligatorio y sin los cuales el envío del formulario no es posible, pues bien en el ejemplo además de definir campos de tipo obligatorios y mostrar los errores producidos por los mismos, mantendremos informado al usuario con avisos de que la información introducida en un campo no obligatorio no es del todo correcta. En el ejemplo el usuario podrá enviar el formulario en caso de tener avisos pero no en el caso de que el formulario cuente con errores en campos de tipo obligatorio. En todo momento tendremos visible un listado de errores que mostrará al usuario el estado en el que se encuentra cada uno de los campos del formulario.
Este es un ejemplo de referencia y no aplicable a cualquier tipo de formulario ya que según vaya variando el código HTML del formulario habrá que realizar adaptaciones en el código JavaScript, de todas formas podréis ver que gracias a la sencillez de jQuery la adaptación de código según el formulario no es tan complicada. A continuación os muestro como quedaría el formulario con las validaciones:
:: Listado de errores ::
- El campo obligatorio nombre se encuentra vacio
- El campo obligatorio apellidos se encuentra vacio
- Aviso: El campo provincia se encuentra vacio
- Aviso: El campo telefono se encuentra vacio
- El campo obligatorio mail se encuentra vacio
- El campo obligatorio comentario se encuentra vacio
- Aviso: El campo adjunto se encuentra vacio
- Debe seleccionar su sexo: Mujer, Hombre
Descargar ejemplo: demo_validaciones.js (39,52kb)
Ejemplo Validaciones con jQuery: El Formulario HTML
Código HTML
<form enctype="multipart/form-data" method="post" action="?x=1">
<fieldset>
<legend>Formulario de contacto</legend>
<p class="obligatorios">* Campos obligatorios</p>
<fieldset>
<legend>Datos personales</legend>
<label for="nombre" accesskey="1">* Nombre
<input class="obligatorio" tabindex="1"/></label>
<label for="apellidos" accesskey="2" >* Apellidos
<input class="obligatorio" tabindex="2"/></label>
<label for="provincia" accesskey="3">Provincia
<input tabindex="3" /></label>
<label for="telefono" accesskey="4">Teléfono
<input tabindex="4" /></label>
<label for="email" accesskey="5">* Email
<input class="obligatorio" tabindex="5" /></label>
<fieldset>
<p>Sexo</p>
<label class="radio" for="mujer" accesskey="6">Mujer
<input class="obligatorio" tabindex="6" value="mujer"/></label>
<label class="radio" for="hombre" accesskey="7">Hombre
<input class="obligatorio" tabindex="7" value="hombre"/></label>
</fieldset>
</fieldset>
<fieldset>
<legend>Otros datos</legend>
<label for="comentario" accesskey="8">* Comentario<textarea class="obligatorio" rows="10" cols="4" tabindex="8"></textarea></label>
<label for="importancia" accesskey="9">Importancia
<select tabindex="9">
<option value="alta">alta</option>
<option value="media">media</option>
<option value="baja">baja</option>
</select>
</label>
<label for="adjunto" accesskey="A">Adjuntar archivo
<input tabindex="10"/></label>
<input value="100000">
<label for="boletin" accesskey="B">Deseo recibir boletín informativo
<input tabindex="11" value="si" /></label>
</fieldset>
<input value="Enviar" />
</fieldset>
</form>
A la hora de hacer el formulario HTML hay tres puntos a resaltar:
- El form deberá llevar un enctype=”multipart/form-data” ya que en nuestro ejemplo queremos dar la posibilidad al usuario de enviar archivos adjuntos
- Todos los campos (input, select, textarea) deberán estar englobados por su respectivo label:
Ejemplo
3.
<label for="nombre" accesskey="1">* Nombre
<input class="obligatorio" tabindex="1"/></label>
- Cada campo llevará un tabindex, cuyo valor indicará el orden en que debe ser rellenado dicho campo.
Ejemplo Validaciones con jQuery: Validación JS
Eventos
Como dije al principio, el objetivo es conseguir realizar unas validaciones en tiempo real, para ello necesitamos que cada vez que el usuario rellene algún campo se haga una llamada a la función JavaScript encargada de comprobar que los datos introducidos son correctos. Para conseguir esto utilizamos el evento blur de jQuery.
Código JS
array_campos = $("#form_mail label");
array_sexo = $("#datos_sexo label");
var aviso_sexo = true;
var errores_validacion = false;
$("#form_mail input, #form_mail select, #form_mail textarea")
.blur(function (event) {
comprobar_campo($(this), array_campos, array_sexo, false);
event.preventDefault();
});
$("#envio")
.click(function (event) {
var errores_validacion = comprobar_campo($(this), array_campos, array_sexo, true);
if(errores_validacion)
event.preventDefault();
});
Tenemos dos eventos, por un lado el blur que como ya hemos dicho llamará a la función comprobar_campo() cada vez que se produzca un cambio en alguno de los campos del formulario y por otro lado el evento click de jQuery que llamará a la función comprobar_campo() al pinchar sobre el boton “enviar”
La función comprobar_campo() será la encargada de comprobar que los datos introducidos por el usuario son correctos y recibira 4 parametros:
- $(this): El elemento que recibe el evento
- array_campos: Array que contiene todo el conjunto de labels con sus correspondientes campos.
- array_sexo: Contiene el label y los radiobuttons del apartado sexo. Para este caso hay que hacer una comprobación especial por lo que lo almacenaremos en una variable a parte. Hablaré mas adelante de este caso.
- Valor booleno (true, false) que tomara el valor true para el caso del evento click y false para el evento blur.
Mediante event.preventDefault(); evitamos que el formulario sea enviado para el caso del evento .blur y para el evento click en caso de que se produzcan errores.
if(errores_validacion)
event.preventDefault();
Comprobar valores introducidos: function comprobar_campo()
Código JS
function comprobar_campo(campo, array_campos, array_sexo, enviar){
if(enviar)
var orden = $(array_campos).length - 1;
else
var orden = campo.attr("tabindex");
var j = 0;
for(i=0; i < orden; i++)
{
var valor = $(array_campos[i]).children().attr("value");
var nombre_campo = $(array_campos[i]).children().attr("name");
var tipo = $(array_campos[i]).children().attr("class");
if(valor == undefined)
{
if(tipo == "obligatorio" || tipo == "obligatorio marcado")
form_error($(array_campos[i]).children(), "vacio")
else
form_aviso($(array_campos[i]).children(), "vacio")
}
else{
if(nombre_campo == "apellidos")
comprobar_apellidos($(array_campos[i]).children())
else if(nombre_campo == "telefono")
comprobar_telefono($(array_campos[i]).children())
else if(nombre_campo == "email")
comprobar_email($(array_campos[i]).children())
else{
var estado_campo = $(array_campos[i]).children().attr("class")
if(estado_campo == "obligatorio marcado" || estado_campo == "marcado" )
{
$(array_campos[i]).children().removeClass("marcado")
form_correcto($(array_campos[i]).children(), tipo)
}
}
}
if(nombre_campo == "sexo")
{
var marcado_sexo = $(array_sexo[j]).children().attr("checked");
if(marcado_sexo)
aviso_sexo = false;
j++;
}
}
if(aviso_sexo && j==2)
{
form_error($(array_campos[5]).children(), "sexo")
}
if($("#listado_errores ol li.error").length == 0)
return false
else
return true
}
La función comprobar_campo será la encargada de decir si los datos introducidos por el usuario son correctos o no y en caso de que no lo sean que tipo de error mostrar.
Lo primero que hace la función es comprobar que campos son los que tiene que validar. Si por un lado el usuario a pulsado el botón enviar esta tendrá que comprobar todos los campos del formulario.
if(enviar)
var orden = $(array_campos).length - 1;
por el contrario si el usuario simplemente acaba de rellenar un campo tomaremos el tabindex del campo modificado y realizaremos las comprobaciones sobre este y los campos anteriores al mismo para evitar que el usuario se deje campos vacios por el camino.
else
var orden = campo.attr("tabindex");
mediante un bucle recorremos los campos que nos interesan y capturamos tres atributos que nos serán de gran ayuda:
- El valor del campo:
var valor = $(array_campos[i]).children().attr("value");
- El nombre del campo:
var nombre_campo = $(array_campos[i]).children().attr("name");
- La clase del campo:
var tipo = $(array_campos[i]).children().attr("class");
El primer valor contendrá el dato introducido por el usuario y por la tanto será el valor a validar, el segundo nos servirá para crear el listado de errores y el tercero lo utilizaremos para marcar los campos con un tipo de error determinado y asignarle los estilos de este tipo de error.
La primera y más sencilla comprobación es testear que el campo a validar no se encuentre vacio
if(valor == undefined)
{
if(tipo == "obligatorio" || tipo == "obligatorio marcado")
form_error($(array_campos[i]).children(), "vacio")
else
form_aviso($(array_campos[i]).children(), "vacio")
}
Si el campo se encuentra vacío comprobamos si este es de tipo obligatorio y si lo es llamamos a la función encargada de gestionar los errores (form_error()), en caso contrario simplemente avisaremos al usuario mediante la función (form_aviso()).
Los parámetros que pasaremos a estas funciones serán el campo que ha producido el error o aviso y el tipo de error que se ha producido, en este caso el aviso de campo vacío (”vacio”).
En caso de que el campo no este vacío pasaremos a comprobar que el valor introducido es válido para ese caso concreto.
else{
if(nombre_campo == "apellidos")
comprobar_apellidos($(array_campos[i]).children())
else if(nombre_campo == "telefono")
comprobar_telefono($(array_campos[i]).children())
else if(nombre_campo == "email")
comprobar_email($(array_campos[i]).children())
Según el nombre del campo que sea llamamos a su función asignada para validar su valor.
Por último si el valor introducido es correcto llamaremos a la función encargada de marcar el campo como valido.
else{
var estado_campo = $(array_campos[i]).children().attr("class")
if(estado_campo == "obligatorio marcado" || estado_campo == "marcado" )
{
$(array_campos[i]).children().removeClass("marcado")
form_correcto($(array_campos[i]).children(), tipo)
}
}
Como comente antes para el caso del tipo de sexo tenemos que hacer una validación específica ya que dentro del label no tenemos un único campo sino que tenemos dos. Este procedimiento de validación habría que hacerlo en caso de que tuviéramos otro caso de campos múltiples como puede ser por ejemplo un conjunto de checkbox que utilizamos para solicitar las preferencias de un usuario.
if(nombre_campo == "sexo")
{
var marcado_sexo = $(array_sexo[j]).children().attr("checked");
if(marcado_sexo)
aviso_sexo = false;
j++;
}
}
if(aviso_sexo && j==2)
{
form_error($(array_campos[5]).children(), "sexo")
}
if($("#listado_errores ol li.error").length == 0)
return false
else
return true
Lo primero que hago es comprobar si alguno de los radio se encuentran marcados y si es así pongo la variable de control(aviso_sexo) a false. En caso de que hayamos comprobado todos los radio (en nuestro caso j=2) y aviso_sexo siga con su valor inicial(true) llamaremos a la función de error.
Funciones de validación especifica
Validación de apellidos
function comprobar_apellidos(apellidos){
$("#e_apellidos").remove();
v_apellidos = $(apellidos).attr("value");
var er_apellidos = / /
if(!er_apellidos.test(v_apellidos))
form_aviso(apellidos, "apellidos")
else
{
var estado_campo = $(apellidos).attr("class")
if(estado_campo == "obligatorio marcado" || estado_campo == "marcado" )
{
$(apellidos).removeClass("marcado")
form_correcto(apellidos, "apellidos")
}
}
}
Mediante esta función comprobaremos que por lo menos se han introducido dos apellidos y en caso de no ser así simplemente lanzaremos un aviso
La primera línea de la función se encarga simplemente de eliminar el error del listado de errores. A continuación nos apoyamos en una expresión regular para comprobar que el valor introducido contenga por lo menos un espacio.
Código Js
var er_apellidos = / /
En caso de no ser así llamamos a form_aviso, por el contrarió en caso de existir y estar marcado con la clase “marcado” la función llamada sería form_correcto() y el marcado sería eliminado.
Validacion de telefono
function comprobar_telefono(telefono){
$("#a_telefono").remove();
v_telefono = $(telefono).attr("value");
var er_tlfono = /^([0-9\s\+\-])+$/
var num_telefono = v_telefono.length
if(!er_tlfono.test(v_telefono))
form_aviso(telefono, "no-num")
else if(num_telefono < 9)
form_aviso(telefono, "corto")
else
{
var estado_campo = $(telefono).attr("class")
if(estado_campo == "obligatorio marcado" || estado_campo == "marcado" )
{
$(telefono).removeClass("marcado")
form_correcto(telefono)
}
}
}
En este caso comprobaremos que solo se introduzcan números y determinados símbolos como +,- y un mínimo de 9 dígitos. Para el caso de los nueve dígitos simplemente comprobamos que v_telefono.length < 9 y si es así lanzamos un aviso de tipo “corto”. Para el caso de los símbolos el funcionamiento vuelve a ser el mismo que hemos visto para los apellidos, utilizamos una expresión regular y según sea el resultado lanzamos el aviso de tipo “no-num” o no. La expresión regular utilizada:
Código Js
var er_tlfono = /^([0-9\s\+\-])+$/
Con esta expresión estamos diciendo que queremos que el valor empiece por un número del 0 al 9, espacio en blanco, símbolo + o menos y se repita una o mas veces hasta el final.
Validación de email
function comprobar_email(email){
$("#e_email").remove();
v_email = $(email).attr("value");
var er_email = /^(.+\@.+\..+)$/
if(!er_email.test(v_email))
form_error(email, "email")
else
{
var estado_campo = $(email).attr("class")
if(estado_campo == "obligatorio marcado" || estado_campo == "marcado" )
{
$(email).removeClass("marcado")
form_correcto(email)
}
}
}
Volvemos a utilizar una nueva expresión regular:
Código Js
var er_email = /^(.+\@.+\..+)$/
Empezamos con un caracter como mínimo seguido de una @, seguida de uno o mas caracteres, un punto y uno o mas caracteres hasta el final.
Todas estas funciones vistas se podrían modificar para hacerlas más estrictas pero para este caso ya sería liarse demasiado :).
Salida de error y aviso
Voy a comentar solo la función de error ya que la de aviso tiene prácticamente el mismo funcionamiento
function form_error(campo, error)
{
$(campo).animate({
backgroundColor: "#FFE8E8",
color: "#000"
}, 1500 );
$(campo).addClass("marcado")
var id_error = "#e_" + $(campo).attr("name")
switch(error)
{
case "vacio":
if($(id_error).attr("class") == undefined)
{
$("#listado_errores ol").append("<li id='e_" + $(campo).attr("name") + "' class='error'><span>El campo obligatorio <strong>" + $(campo).attr("name") + "</strong> se encuentra vacio</span></a></li>")
}
break;
case "email":
if($(id_error).attr("class") == undefined)
{
$("#listado_errores ol").append("<li id='e_" + $(campo).attr("name") + "' class='error'><span>El <strong>e-mail</strong> introducido es incorrecto</span></a></li>")
}
break;
case "sexo":
if($(id_error).attr("class") == undefined)
{
$("#listado_errores ol").append("<li id='e_" + $(campo).attr("name") + "' class='error'><span>Debe seleccionar su <strong>sexo</strong>: Mujer, Hombre</a></li>")
}
break;
}
}
Lo primero que hacemos es utilizar el método animate de jQuery para conseguir cambiar el color de fondo y de fuente progresivamente durante un tiempo de 1,5 segundos.
$(campo).animate({
backgroundColor: "#FFE8E8",
color: "#000"
}, 1500 );
jquery.color.js: El método animate de jQuery no es capaz por si solo de producir una animación sobre el color de fondo de un elemento. Para poder hacer esto necesitamos apoyarnos en el plugin de jQuery: jquery.color.js. Podéis encontrarlo en la carpeta “js” del ejemplo bajo el nombre de colors.js.
Siguiendo con la explicación de la función de error, asignaremos la clase “marcado” al campo para saber que ese campo está produciendo un error o aviso y creamos el identificador de error (id_error) utilizando el name del campo. Este id lo utilizaremos para asignarlo al li del listado de errores.
$(campo).addClass("marcado")
var id_error = "#e_" + $(campo).attr("name")
Para finalizar nos fijamos en el segundo parámetro que recibe la función (error) que nos dará el tipo de error que se esta produciendo y según su valor mostraremos un tipo de error determinado en el listado de errores, que estará formado por un li con un id: e_[nombre_del_campo] un class “error” y el mensaje. Para el caso de la función aviso el id será del tipo: a_[nombre_del_campo] y utilizara un class “aviso”.
Salida correcta
Está función se encargará de marcar los campos que contenían fallos como válidos y producirá una determinada animación gracias al método animate.
$(campo).addClass("marcado")
function form_correcto(campo, tipo)
{
$(campo).animate({
backgroundColor: "#CDEFB4",
color: "#000"
}, 800 );
$(campo).animate({
backgroundColor: "#FFF",
color: "#999"
}, 800 );
$(campo).removeClass("marcado")
c_correcto = $(campo).attr("name");
if(tipo == "obligatorio" || tipo == "obligatorio marcado")
{
e_correcto = "#e_" + c_correcto;
$(e_correcto).remove();
}
else
{
a_correcto = "#a_" + c_correcto;
$(a_correcto).remove();
}
}
En esta función volvemos a utilizar el mismo método animate que utilizamos para la función de error y aviso pero con otros valores para los estilos. Eliminamos la clase marcado para avisar de que el campo es válido y por último creamos la variable c_correcto con el nombre del campo para eliminar el mensaje de error o aviso según sea el tipo del campo.
Ejemplo Validaciones con jQuery: Envío del formulario con PHP
Código PHP
<?php
if($_GET["x"] == 1)
{
// primero hay que incluir la clase phpmailer para poder instanciar
//un objeto de la misma
require "includes/class.phpmailer.php";
//instanciamos un objeto de la clase phpmailer al que llamamos
//por ejemplo mail
$mail = new phpmailer();
//Definimos las propiedades y llamamos a los mtodos
//correspondientes del objeto mail
//Con PluginDir le indicamos a la clase phpmailer donde se
//encuentra la clase smtp que como he comentado al principio de
//este ejemplo va a estar en el subdirectorio includes
$mail->PluginDir = "includes/";
//Con la propiedad Mailer le indicamos que vamos a usar un
//servidor smtp
$mail->Mailer = "smtp";
//Asignamos a Host el nombre de nuestro servidor smtp
$mail->Host = "nombre_host";
//Le indicamos que el servidor smtp requiere autenticacin
$mail->SMTPAuth = false;
//Le decimos cual es nuestro nombre de usuario y password
//$mail->Username = "usuario";
//$mail->Password = "contraseña";
//Indicamos cual es nuestra direccin de correo y el nombre que
//queremos que vea el usuario que lee nuestro correo
$mail->From = "[email protected]";
$mail->FromName = "nombre";
//el valor por defecto 10 de Timeout es un poco escaso dado que voy a usar
//una cuenta gratuita, por tanto lo pongo a 30
$mail->Timeout=30;
$nombre_archivo = $HTTP_POST_FILES['adjunto']['name'];
$tamano_archivo = $HTTP_POST_FILES['adjunto']['size'];
echo $tamano_archivo;
if($tamano_archivo < 1000)
{
if (move_uploaded_file($HTTP_POST_FILES['adjunto']['tmp_name'], "adjuntos/".$nombre_archivo) == false){
echo "Ocurrió algún error al subir el fichero al servidor. El fichero adjunto no pudo ser enviado";
}
else
{
$mail->AddAttachment("adjuntos/".$nombre_archivo,$nombre_archivo);
$subido = true;
}
}
else
echo "El tamaño del archivo es demasiado elevado. Maximo tamaño de ficheros permitido: 100Kb";
//Indicamos cual es la direccin de destino del correo
$mail->AddAddress("[email protected]");
//Asignamos asunto y cuerpo del mensaje
//El cuerpo del mensaje lo ponemos en formato html, haciendo
//que se vea en negrita
$mail->Subject = "Prueba de phpmailer";
$mail->Body = "<h1>Nuevo contacto</h1>";
foreach($_POST as $nombre_campo => $valor){
if($nombre_campo != "enviar" && $nombre_campo != "MAX_FILE_SIZE")
$mail->Body = $mail->Body."<p><strong>".$nombre_campo.": </strong>".$valor."</p>";
}
//Definimos AltBody por si el destinatario del correo no admite email con formato html
$mail->AltBody = "Mensaje de prueba mandado con phpmailer en formato solo texto";
//se envia el mensaje, si no ha habido problemas
//la variable $exito tendra el valor true
$exito = $mail->Send();
//Si el mensaje no ha podido ser enviado se realizaran 4 intentos mas como mucho
//para intentar enviar el mensaje, cada intento se hara 5 segundos despues
//del anterior, para ello se usa la funcion sleep
$intentos=1;
while ((!$exito) && ($intentos < 5)) {
sleep(5);
//echo $mail->ErrorInfo;
$exito = $mail->Send();
$intentos=$intentos+1;
}
if(!$exito)
{
echo "Problemas enviando correo electrnico a ".$valor;
echo "<br>".$mail->ErrorInfo;
}
else
{
echo "Mensaje enviado correctamente";
}
if($subido)
unlink("adjuntos/".$nombre_archivo);
}
?>
Respecto al código PHP que utilizamos para enviar nuestro formulario HTML lo mas importante a recalcar es que utilizamos la clase PHPMailer que nos permite enviar archivos adjuntos en nuestros correos. Para saber más acerca de esta clase os recomiendo que le echeis un vistazo un tutorial en español bastante bueno: Tutorial PHPMailer en programacion.com
En el código que estoy utilizando tengo configurado a false el SMTPAuth con lo que estoy diciendo que el servidor smtp no requiere autentificación. En el caso de que vuestro servidor smtp requiera autentificación tendréis que poner a true la variable SMTPAuth y descomentar y configurar el username y password tal que asi:
//Le indicamos que el servidor smtp requiere autenticacin
$mail->SMTPAuth = true;
//Le decimos cual es nuestro nombre de usuario y password
$mail->Username = "usuario";
$mail->Password = "contraseña";
Enviar archivo adjunto con PHPMailer
Para el envio de un archivo adjunto utilizaremos el siguiente código
$nombre_archivo = $HTTP_POST_FILES['adjunto']['name'];
$tamano_archivo = $HTTP_POST_FILES['adjunto']['size'];
if($tamano_archivo < 1000)
{
if (move_uploaded_file($HTTP_POST_FILES['adjunto']['tmp_name'], "adjuntos/".$nombre_archivo) == false){
echo "Ocurrió algún error al subir el fichero al servidor. El fichero adjunto no pudo ser enviado";
}
else
{
$mail->AddAttachment("adjuntos/".$nombre_archivo,$nombre_archivo);
$subido = true;
}
}
else
echo "El tamaño del archivo es demasiado elevado. Maximo tamaño de ficheros permitido: 100Kb";
Para poder enviar un archivo adjunto por correo lo primero que tenemos que hacer es subirlo a una ubicación determinada en nuestro servidor, asi que empezaremos cojiendo el nombre y tamaño del archivo que el usuario a seleccionado en el campo de tipo fichero y si el tamaño del mismo es inferior a 1kb subimos el archivo a nuestra carpeta adjuntos.
move_uploaded_file($HTTP_POST_FILES['adjunto']['tmp_name'], "adjuntos/".$nombre_archivo)
Una vez que hayamos subido con exito el archivo al servidor utilizaremos el método AddAttachment para adjuntar el archivo en el correo.
Con esto tendriamos listo nuestro formulario con sus validaciones jQuey. Tengo que decir que para que este código estuviera completo habría que realizar unas validaciones de lado servidor ya que las validaciones por javascript no resultan seguras. Si queréis echar un vistazo a algún tutorial donde se hable de validaciones del lado servidor os recomiendo http://www.desarrolloweb.com/scripts/php/validacion-php.php para PHP y http://www.desarrolloweb.com/scripts/asp/validaciones-formularios-asp.php para ASP.
Via: http://www.jmocana.eu/2009/02/09/validaciones-con-jquery/