danielhq
8/13/2014 - 3:45 PM

2 Step Form.js

$(document).ready(function() {

	var DEBUG = false;
	function formfiller1() {
		$("input").add("textarea").not("[type=button], [type=submit]").each(function() {
			if ( $(this).hasClass('email')) {
				$(this).attr("value" ,"daniel@mail.it");
			} else {
				$(this).attr("value","test");
			}
		});
	}
	$(window).keydown(function(event) {
		if ( event.keyCode === 16 && DEBUG === true ) {
			console.log("filler");
			formfiller1();
		}
	});
	/**
	 * Oggetto con opzioni di default
	 * @type {Object}
	 * @Proprety {string} errorClass: classe css dell'errore
	 * @Property {string} errorTag: tagName del errore (ex: span, div)
	 * @Method errorSelector: ritorna un selettore qualificato per un uso più sicuro (evitare conflitti)
	 * @Method() composeTag(selector,cssClass, msg): ritorna un tag 'selector' con classe 'cssClass' contentente 'msg'
	 */

	var settings = {
		errorClass : 'error',
		errorTag: 'span',
		errorSelector: function() {
			return this.errorTag + "." + this.errorClass;
		},
		composeTag : function(selector,cssClass, msg) {
			return '<' + selector + ' class="' + cssClass + '">' + msg + '</' + selector + '>';
		}
	};


	/**
	 * [form description]
	 * @type {Object}
	 */

	var form = {
		steps: 2,
		currentStep: 1,
		stepsClass: '.steps-widget__step',
		stepsActiveClass:  '.steps-widget__step-is-active',
		next: function() {
			return ( this.currentStep === this.steps ) ? false : ++this.currentStep;
		},
		prev: function(){
			return ( this.currentStep === 1 ) ? false : --this.currentStep;
		}
	};


	/**
	 * Handler per i messaggi
	 * @type {Object}
	 * @Method() add(elem, tag): aggiunge 'tag' a elem solo nel caso non ci sia già
	 * @Method() remove(elem, removedSelctor): rimuove 'removedSelector' da 'elem'
	 */

	var messages = {
		empty: "il campo è obbligatorio",
		email: "Per cortesia, inserisci un'e-mail corretta",
		add: function(elem, tag) {
			// Controllo che l'input non abbia già degli errori associati
			if ( elem.siblings(settings.errorSelector()).length > 0 ) {
				elem.siblings(settings.errorSelector()).each(function() {
					if ( $(this).text() === $(tag).text() ) {
						//console.log("error already added");
						return;
					} else {
						this.remove(elem, settings.errorSelector());
						elem.after(tag);
					}
				});
			} else  {
				elem.after(tag);
			}
		},
		remove: function(elem, removedSelctor) {
			elem.next(removedSelctor).remove();
		}
	};


	/**
	 * Regole di validazione
	 * @type {Object}
	 * @return [true | false] Ritorna true se il valore è valido
	 */

	var rules = {
		isEmail: function(val) {
			var reg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
			return reg.test(val);
		},
		isEmpty: function(val) {
			return val === "" ? true : false;
		}
	};


	/**
	 * Costruttore dello step
	 * @type {Object, Class}
	 * @Proprety {string} name : classe o id dell contenitore dello step
	 * @Proprety {boolean} hasError : boolean
	 * @Method() countInputs(): Ritorna il numero di input all'interno di step
	 * @Method() getInputs(): Ritorna tutti gli input e textarea da validare all'interno di step
	 * @Constructor : var step1 =  new StepSettings('.step-1');
	 */

	function StepSettings(name) {
		this.name = name;
		this.hasError = false;
		validInputs= 0;
	}

	StepSettings.prototype.countInputs = function() {
		if ( $(this.name).length === 0 ) {
			throw( this.name + " element not found");
		} else {
			var inputs = $(this.name).find("input").length,
			textareas = $(this.name).find("textarea").length;
			return inputs + textareas;
		}
	};
	StepSettings.prototype.getInputs = function() {
		return $(this.name + ' input').add( this.name  + ' textarea');
	};


	/**
	 * Funzione di validazione, viene chiamata per ogni input tramite un $.each()
	 * @param  {DOMnode} elem l'input
	 * @return {boolean}      Ritorna true se è valido rispetto alle regole impostate nelle classi o false
	 */

	function valid(elem) {
		var tag,
		isValid = true;
		if (elem.hasClass('required')) {
			if ( rules.isEmpty( elem.val() ) ) {
				tag = settings.composeTag(settings.errorTag, settings.errorClass, messages.empty);
				messages.add(elem, tag);
				isValid = false;
			}
		}
		if (elem.hasClass('email') ) {
			if ( !rules.isEmail( elem.val() ) ) {
				tag = settings.composeTag(settings.errorTag, settings.errorClass, messages.email);
				messages.add(elem, tag);
				isValid = false;
			}
		}
		elem.attr("value", elem.val());
		return isValid;
	}

		function validateEach(step, inputs) {
			inputs.each(function() {
				if  ( valid( $(this) ) ) {
					messages.remove($(this), settings.errorTag);
					step.validInputs++;
				}
			});
		}

	// Step 1
	$('body').on("click", ".js-btn__next", function(event) {
		event.preventDefault();
		if ($(this).hasClass('btn__disabled')) {
			return false;
		}
		var step1 = new StepSettings('.step-1'),
			step2 = new StepSettings('.step-2'),
			numberInputs, inputs;



		if ( form.currentStep === 1 ) {

			numberInputs = step1.countInputs();
			inputs = step1.getInputs();
			step1.validInputs = 0;
			validateEach(step1, inputs);

			if ( step1.validInputs === numberInputs ) {
				step1.hasError = false;
				form.next();
				$(step1.name).fadeOut('fast', function() {
					$(step2.name).fadeIn('fast');
					$(".steps-widget__step").each(function() {
						$(this).toggleClass('steps-widget__step-is-active');
					});
					$(".js-btn__back").removeClass('btn__disabled');
					$(".js-btn__next").text('Invia');
				});
			} else {
				step1.hasError = true;
			}
		} else if ( form.currentStep === 2 ) {
			// Step 2 validation
			numberInputs = step2.countInputs();
			inputs = step2.getInputs();
			step2.validInputs = 0;
			validateEach(step2, inputs);

			if ( step2.validInputs === numberInputs ) {
				step2.hasError = false;
				console.log("step2 complete");
				$('form').trigger('submit');
				return true;
			} else {
				step2.hasError = true;
			}
		}


	});

	$('body').on("click", ".js-btn__back", function() {
		if ($(this).hasClass('btn__disabled')) {
			return false;
		}
		form.prev();
		$(".steps-widget__step").each(function() {
			$(this).toggleClass('steps-widget__step-is-active');
		});

		$('.step-2').fadeOut('fast', function() {
			$('.step-1').fadeIn('fast');
		});
	});

	$(".js-send-info").on("click", function(e) {
		e.preventDefault();
		var step1 = new StepSettings('.step-1');
		form.steps = 1;
		var numberInputs = step1.countInputs(),
			inputs = step1.getInputs();
		step1.validInputs = 0;
		validateEach(step1, inputs);

		if ( step1.validInputs === numberInputs ) {
			step1.hasError = false;
			$('form').trigger('submit');

		}
	});
	$(".js-send-friend").on("click", function(e) {
		e.preventDefault();
		var step1 = new StepSettings('.step-1');
		form.steps = 1;
		var numberInputs = step1.countInputs(),
			inputs = step1.getInputs();
		step1.validInputs = 0;
		validateEach(step1, inputs);

		if ( step1.validInputs === numberInputs ) {
			step1.hasError = false;
			$('form').trigger('submit');

		}
	});


	$("form").submit(function (event) {

	  if (testEmail($('.email').val())) {
	    $('.errore').text("").text("success");


	  } else {
	    $('.errore').text("").text("success");

	  }
	  return false
	});
});