Add Me!Close Menu Navigation
Add Me!Categorías abiertas del menú

Formulario en varios pasos usando jQuery

Muchas veces nos encontramos con que tenemos que rellenar un formulario con una cantidad inmensa de datos, lo cuál hace que el proceso sea pesado y que sobrecargue la página de información.

Mediante jQuery y el plugin Fancy Sliding Form podemos ofrecer una solución basada en tabs. Veámoslo:

Fichero HTML

<h1>Formulario usando tabs y jQuery</h1>
<div id="wrapper">
	<div id="steps">
		<form id="formElem" name="formElem" action="" method="post">
			<fieldset class="step">
				<legend>Account</legend>
				<p>
					<label for="username">User name</label>
					<input id="username" name="username" />
				</p>
				<p>
					<label for="email">Email</label>
					<input id="email" name="email" type="email" />
				</p>
				<p>
					<label for="password">Password</label>
					<input id="password" name="password" type="password" />
				</p>
			</fieldset>
			<fieldset>
			...
			</fieldset>
		</form>
	</div>
	<div id="navigation" style="display:none;">
		<ul>
			<li class="selected">
				<a href="#">Account</a>
			</li>
			<li>
				<a href="#">Personal Details</a>
			</li>
			<li>
				<a href="#">Payment</a>
			</li>
			<li>
				<a href="#">Settings</a>
			</li>
			<li>
				<a href="#">Confirm</a>
			</li>
		</ul>
	</div>
</div>

Código jQuery

En nuestra función primero debemos asegurarnos que se muestra el slider. Para ello necesitamos calcular el ancho de los elementos. Además debemos vigilar el sliding cuando el tab recibe los inputs. Cuando el usuario clica sobre el último input de un fieldset, debemos colocar en posición el próximo fieldset y colocar el foco en el primer input.

La validación del formulario está basada en todos los inputs obligatorios. Si pasamos al siguiente fieldset sin haber completado correctamente todos los inputs, deberemos advertir al usuario con un fondo rojo y añadir un pequeño mensaje de error.

Si no hubieran errores, se mostrará un “check ok” para informar que no todo está correcto. Si alguno de los pasos contiene errores, el formulario no será enviado.

He aquí el código JS:

$(function() {
	/*
	número de fieldsets
	*/
	var fieldsetCount = $('#formElem').children().length;
 
	/*
	Posición actual del fieldset / link de navegación
	*/
	var current 	= 1;
 
	/*
	suma y almacena las anchuras de cada uno de los fieldsets
	establece el sumatoria total como ancho total del elemento
	*/
	var stepsWidth	= 0;
    var widths 		= new Array();
	$('#steps .step').each(function(i){
        var $step 		= $(this);
		widths[i]  		= stepsWidth;
        stepsWidth	 	+= $step.width();
    });
	$('#steps').width(stepsWidth);
 
	/*
	Para solucionar los problemas de IE, se pone el foco in el primer elemento del formulario
	*/
	$('#formElem').children(':first').find(':input:first').focus();	
 
	/*
	Muestra la barra de navegación
	*/
	$('#navigation').show();
 
	/*
	Cuando se clica sobre el link de navegación el formulario se desplaza al correspondiente fieldset
	*/
    $('#navigation a').bind('click',function(e){
		var $this	= $(this);
		var prev	= current;
		$this.closest('ul').find('li').removeClass('selected');
        $this.parent().addClass('selected');
		/*
		Almacenamos la posición del link
		*/
		current = $this.parent().index() + 1;
		/*
		anima / slide al siguiente o al correspondiente fieldset. El orden de los links en la navegación es el orden de los fieldsets. Además, después del sliding, el foco se posiciona sobre el primer elemento del siguiente fieldest.
		Si se clica sobre el último link (confirmación), se validan todos los fieldsets, sino se valida el fieldset anterior antes de que se produzca el slide
		*/
        $('#steps').stop().animate({
            marginLeft: '-' + widths[current-1] + 'px'
        },500,function(){
			if(current == fieldsetCount)
				validateSteps();
			else
				validateStep(prev);
			$('#formElem').children(':nth-child('+ parseInt(current) +')').find(':input:first').focus();
		});
        e.preventDefault();
    });
 
	/*
	Clicando el el tab (en el último input de cada fieldset), se fuerza a ir al "siguiente paso"
	*/
	$('#formElem > fieldset').each(function(){
		var $fieldset = $(this);
		$fieldset.children(':last').find(':input').keydown(function(e){
			if (e.which == 9){
				$('#navigation li:nth-child(' + (parseInt(current)+1) + ') a').click();
				/* force the blur for validation */
				$(this).blur();
				e.preventDefault();
			}
		});
	});
 
	/*
	validación de errores de todos los fieldsets 
	Almacena posibles errores en $('#formElem').data()
	*/
	function validateSteps(){
		var FormErrors = false;
		for(var i = 1; i < fieldsetCount; ++i){
			var error = validateStep(i);
			if(error == -1)
				FormErrors = true;
		}
		$('#formElem').data('errors',FormErrors);
	}
 
	/*
	Valida un fieldset y retorna -1 si hay errores o 0 si no los hay
	*/
	function validateStep(step){
		if(step == fieldsetCount) return;
 
		var error = 1;
		var hasError = false;
		$('#formElem').children(':nth-child('+ parseInt(step) +')').find(':input:not(button)').each(function(){
			var $this 		= $(this);
			var valueLength = jQuery.trim($this.val()).length;
 
			if(valueLength == ''){
				hasError = true;
				$this.css('background-color','#FFEDEF');
			}
			else
				$this.css('background-color','#FFFFFF');
		});
		var $link = $('#navigation li:nth-child(' + parseInt(step) + ') a');
		$link.parent().find('.error,.checked').remove();
 
		var valclass = 'checked';
		if(hasError){
			error = -1;
			valclass = 'error';
		}
		$('<span class="'+valclass+'"></span>').insertAfter($link);
 
		return error;
	}
 
	/*
	Si hay errores no se produce el submit
	*/
	$('#registerButton').bind('click',function(){
		if($('#formElem').data('errors')){
			alert('Please correct the errors in the Form');
			return false;
		}
	});
});

Nada más. Podéis ver el ejemplo funcionando aquí y descargar el código del plugin desde aquí

Posts Relacionados: 3 plugins SEO para WP que deberías conocer | 30 sitios donde descargar imágenes gratuitas | Formas de perder el tiempo posicionando webs | Qué hacer si Google te ha penalizado en su ‘last update’ | Menú de subnavegación (CSS+JQuery) | NounProject: Gran colección de iconos vectoriales | Reveal: Ventanas modales con jQuery | Contactable: Formularios accesibles con jQuery | jQuery: 10 snippets útiles que deberías conocer | Formulario en varios pasos usando jQuery |

2 comentarios to “Formulario en varios pasos usando jQuery”

  1. keli dice:

    Muchas gracias!

  2. PyramidHead dice:

    Esta genial !!! pero y mezclarlo con base de datos?

Deja un comentario




Categorías