// -- cette premère partie prépare des fonctions de parsing de code génériques, utilisées ensuite dans les fonctions de validation des différents formulaires 
var $n = {
	/* 	
		hasAttributes : retourne true si l'element passe en parametre correspond a tous les attributs passes, on peut aussi donner des attributs que l'on ne veut pas, afin de filtrer tous les &eacute;lements
		ex : if (hasAttributes(div, {nodeName:"div", className:"foobar"), {className:"idontwant"} ) doStuff();
		ici on recherche tous les DIV qui on la classe "foobar", mais on ne prend pas ceux qui ont la classe "idontwant" ex : <div class="foobar idontwant"> ne sera pas recupere.
	*/
	hasAttr : function(n, a, not) {
		var re, at;
		if (n.nodeType!=1) return false;
		function check(attr) {
			for (var i in attr) {
				at = (typeof n[i]) !="undefined" ? n[i] : n.getAttribute(i);
				re = attr[i] instanceof RegExp ? re : new RegExp("\\b" + attr[i] + "\\b","i");
				if (!at || !re.test(at)) 
					return false;
			}
			return true;
		};
		if (not && check(not))	return false;
		if (check(a)) return true;
		return false;
	},
	/* getByTagName : equivalent a element.getElementsByTagName, mais compatible avec IE5 et IE5.5 pour l'histoire du "*" */
	getByTagName : function(n, tag) {
		return  (tag=="*") ? (n.all ? n.all : n.getElementsByTagName("*")) : n.getElementsByTagName(tag);
	},
	/* fonction qui retourne le premier element correspondant aux attributs donnes */
	node : function(n, a, not) {
		return $n.nodes(n, a, not, true);
	},
	/* fonction qui retourne tous les elements correspondant selon "a" */
	nodes : function(n, a, not, oneNode, arrElms) {
		var aRetElms=[];
		if (!a) a = {};
		if (typeof a == "string") a = {nodeName:a}; //si une chaine de caract&egrave;res pass&eacute;e en param&egrave;tre, cela signifie qu'on ne veut que r&eacute;cup&eacute;rer des tags
		if (a.nodeName && a.nodeName=="*") delete a.nodeName;
		var elms = arrElms || $n.getByTagName(n, (a.nodeName || "*"));
		for (var i=0; i<elms.length; i++) {
			var x = elms[i];
			if ($n.hasAttr(x, a, not)) {
				if (oneNode) return x;
				else aRetElms.push(x);
			}
		}
		if (oneNode) return null;
		return aRetElms;
	},
	/* childs : retourne tous les noeuds enfants de l'element  */
	childs : function(n, a, not) {
		return $n.nodes(n, a, not, false, n.childNodes);
	},
	/* firstchild : retourne le premier noeud enfant de l'element  */
	firstChild : function(n, a, not) {
		return $n.nodes(n, a, not, true, n.childNodes);
	},
	/* lastchild : retourne le dernier noeud enfant de l'element  */
	lastChild : function(n, a, not) {
		var node = $n.nodes(n, a, not, false, n.childNodes);
		return node[node.length-1];
	},
	/* move : permet de se déplacer dans l'arbre  */
	move : function(n, a, not, action) {
		while (n) {
			if ($n.hasAttr(n, a, not)) return n;
			n = n[action];
		}
		return null;
	},
	/* after : retourne le  noeud suivant le noeud courant  */
	after : function(n, a, not) { 
		return $n.move(n, a, not, "nextSibling");
	},
	/* before : retourne le  noeud précédent le noeud courant  */
	before : function(n, a, not) {
		return $n.move(n, a, not, "previousSibling");
	},
	/* parent : retourne le  noeud parent du noeud courant  */
	parent : function(n, a, not) {
		return $n.move(n, a, not, "parentNode");
	}
}

/* raccourcis de fonctions : alias  */
var getNode = $n.node,
	getNodes = $n.nodes,
	getChildNodes = $n.childs,
	getNextSibling = $n.after,
	getPreviousSibling = $n.before,
	getParent = $n.parent,
	hasAttributes = $n.hasAttr,
	getElementsByTagName = $n.getByTagName;

	
// partie principale : collections de fonctions de validation de formulaire, gestion des messages d'erreurs
var formval={
	// --- message d'erreur par défaut
	defaultErrorMessage:"Ce champ est erron\u00E9",
	defaultPosition:"beforefield",
	globalErrorMsg : "",
	callbackfunctions : function() {
		//fixColumns();
		//if (popLayer.pop) popLayer.resize();
	},
	//--- différents tags parsés pour la validation formulaire
	lineInput : {nodeName:"(div|p|li)"},
	validationFunc:{
		// --- requiredgroup : groupes de champs obligatoires
		// le champ en cours doit avoir la proprieté 'requiredgroupothers', qui regroupe les champs obligatoire associés, séparés par une virgule.
		// Si l'un des champs ne satisfait pas la règle required, on retourne false.
		requiredgroup:function(field) {
			var self = this;
			var returnMessage=true;
			var allFields = field.getAttribute('requiredgroupothers').split(',');
			allFields.each(function(field) {
				field = $(field);
				if (self.required(field)!=true) returnMessage = false;
			});
			
			return returnMessage;
			
		},
		
		// --- règle de saisie obligatoire, le msg d'erreur renvoyé est relatif au type du champ de saisie
		required:function(field) {
			var returnMessage=true;
			switch(field.type) {
				case "text":
				case "file":
				case "password":
				case "textarea":
					if (field.value=="") returnMessage="text";
					break;
				case "checkbox":
				case "radio":
					var sameElt = formval.getSameElements(field);
					var onecheck=false;
					for (var i=0; i<sameElt.length; i++) {
						if (sameElt[i].checked)
							onecheck=true;
					}
					if (!onecheck) returnMessage=field.type;
					break;
				case "select-one":
				case "select-multiple":
					if(field.selectedIndex==0) 
						returnMessage="select";
					break;
			}
			return returnMessage;
		},
		
		// --- duo : groupes de champs obligatoires
		// le champ en cours doit avoir la proprieté 'completewith', qui regroupe les champs obligatoire associés, séparés par une virgule.
		// Si l'un des champs ne satisfait pas la règle required, on retourne false.
		duo:function(field) {
			if(field.value=="") return true;
			
			returnMessage = true;
			var allFields = field.getAttribute('completewith').split(',');
			
			for(i=0; i<allFields.length; i++){ 
				if(document.getElementById(allFields[i]).value == '' && document.getElementById(allFields[i]).disabled == false ) returnMessage = false;
			}
			
			return returnMessage;
			
			
		},
		// --- compareAge : règle de comparaison d'age : teste si la différence de 2 années est inférieure à 16 ans
		// règle utilisée exclusivement dans le step 1, pour tester l'age des enfants
		compareAge:function(field){
			var compareTo = document.getElementById(field.getAttribute('comparewith')).value.split('/');
			return !(Math.abs(compareTo[2] - field.value) < 16);
		},
		// --- associatedOptional : permet de rendre un groupe de champ obligatoire, mais la saisie d'un seul champ parmi ce groupe satisfait la règle
		associatedOptional:function(field) {
			var cpt = 0;
			
			if(field.value=="") cpt++;
			
			var allFields = field.getAttribute('optionalwith').split(',');
			
			for(i=0; i<allFields.length; i++){ 
				if(document.getElementById(allFields[i]).value == "" ) cpt++;
			}
			
			if(cpt == allFields.length+1) return false;
			else return true;
			
		},
		// --- associatedOptionalRadio : idem règle ci-dessus, mais pour les radio buttons
		associatedOptionalRadio:function(field) {
			var cpt = 0;
			
			var sameElt = formval.getSameElements(field);
			
			
			for (var i=0; i<sameElt.length; i++) {
				if (sameElt[i].checked && (sameElt[i].value == "no" || sameElt[i].value == "N")) return true;
			}
			cpt++;
			
			
			var allFields = field.getAttribute('optionalwith').split(',');
			
			for(i=0; i<allFields.length; i++){ 
				if(document.getElementById(allFields[i]).value == "" && document.getElementById(allFields[i]).disabled == false ) cpt++;
			}
			
			if(cpt == allFields.length+1) return false;
			else return true;
			
		},
		// --- email : règle de validation d'une adresse email, basée sur regexp
		email:function(field) {return (field.value=="" || !!field.value.match(/^[a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,6}$/i));},
		// --- inf1525 : teste si le montant saisi est inférieur à 1525
		inf1525:function(field) { return (field.value=="" || field.value < 1525); },
		//--- dateValid : teste la validité d'une date
		dateValid:function(field) {
			
			var dateSplit = field.value.split('/');
			
			if(dateSplit.length != 3) return false;
			
			if( !!dateSplit[0].match(/[0-9]{2}/) && !!dateSplit[1].match(/[0-9]{2}/) && !!dateSplit[2].match(/[0-9]{4}/) ){ 
				if(dateSplit[2].charAt(0) > 2) return false;
				if(dateSplit[2].charAt(0) == 2 && dateSplit[2].charAt(1) > 0) return false;
				
				if(dateSplit[1].charAt(0) > 1) return false;
				if(dateSplit[1].charAt(0) == 1 && dateSplit[1].charAt(1) > 2 ) return false;
				
				if(dateSplit[0].charAt(0) > 3) return false;
				if(dateSplit[0].charAt(0) == 3 && dateSplit[0].charAt(1) > 1 ) return false;
				
				return true;
			}
			return false;
		},
		//--- dateValidoptional : teste la validité d'une date comme la règle précédente, mais cette règle est optionnelle (le champ peut être vide)
		dateValidOptional:function(field) {
			if(field.value=="") return true;
			
			var dateSplit = field.value.split('/');
			
			if(dateSplit.length != 3) return false;
			
			if( !!dateSplit[0].match(/[0-9]{2}/) && !!dateSplit[1].match(/[0-9]{2}/) && !!dateSplit[2].match(/[0-9]{4}/) ){ 
				if(dateSplit[2].charAt(0) > 2) return false;
				if(dateSplit[2].charAt(0) == 2 && dateSplit[2].charAt(1) > 0) return false;
				
				if(dateSplit[1].charAt(0) > 1) return false;
				if(dateSplit[1].charAt(0) == 1 && dateSplit[1].charAt(1) > 2 ) return false;
				
				if(dateSplit[0].charAt(0) > 3) return false;
				if(dateSplit[0].charAt(0) == 3 && dateSplit[0].charAt(1) > 1 ) return false;
				
				return true;
			}
			return false;
		},
		date:function(field) {
			var dateSplit = field.value.split('/');
			var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, dateSplit[0]);
			if (date.getDate()!=dateSplit[0] || date.getMonth()!=parseInt(dateSplit[1])-1 || date.getFullYear()!=dateSplit[2]) {
				return false;
			}
			return true;
		},
		dateMax:function(field) {
			if(field.value != ""){
				
				var dateSplit = field.value.split('/');
				
				if(dateSplit.length != 3) return false;
				
				if(dateSplit[1].charAt(0) == 0 ) dateSplit[1] = dateSplit[1].charAt(1);
				if(dateSplit[2].charAt(0) == 0 ) dateSplit[2] = dateSplit[2].charAt(1);
			
				var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, parseInt(dateSplit[0]));
			
				return !(date.getTime()>=new Date().getTime());
			} return true;
		},
		//--- dateMax6mois : teste si la date entrée est antérieure à la date du jour - 6 mois
		dateMax6mois:function(field) {
			if(field.value != ""){
				var dateSplit = field.value.split('/');
				
				if(dateSplit.length != 3) return false;
				
				if(dateSplit[1].charAt(0) == 0 ) dateSplit[1] = dateSplit[1].charAt(1);
				if(dateSplit[2].charAt(0) == 0 ) dateSplit[2] = dateSplit[2].charAt(1);
			
				var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, parseInt(dateSplit[0]));
				
				//15778800000  = nbre millisecondes en 6 mois
				return !((date.getTime() - new Date().getTime()) <= 15778800000);
			} return true;
		},
		//--- dateMax100ans : teste si la date entrée est antérieure à la date du jour - 6 mois
		dateMax70ans:function(field) {
			if(field.value != ""){
				var dateSplit = field.value.split('/');
				
				if(dateSplit.length != 3) return false;
			
				if(dateSplit[1].charAt(0) == 0 ) dateSplit[1] = dateSplit[1].charAt(1);
				if(dateSplit[2].charAt(0) == 0 ) dateSplit[2] = dateSplit[2].charAt(1);
			
				var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, parseInt(dateSplit[0]));
				
				//3155760000000  = nbre millisecondes en 100 ans
				return !((new Date().getTime() - date.getTime()) >= 2209032000000);
			} return true;
		},
		//--- dateMajeur : teste si la date entrée est antérieure à la date du jour - 18 ans
		dateMajeur:function(field) {
			if(field.value != ""){
				var dateSplit = field.value.split('/');
				
				if(dateSplit.length != 3) return false;
			
				if(dateSplit[1].charAt(0) == 0 ) dateSplit[1] = dateSplit[1].charAt(1);
				if(dateSplit[2].charAt(0) == 0 ) dateSplit[2] = dateSplit[2].charAt(1);
			
				var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, parseInt(dateSplit[0]));
				
				return !((new Date().getTime() - date.getTime()) <= 568036800000);
			} return true;
		},
		maxOld25:function(field){ return !((new Date().getFullYear() - field.value) > 25); },
		// --- address : teste la validité d'une addresse
		address:function(field){if (field.value=="") return true; return !!field.value.match(/^[-,\u00E9\u00e8\u00e0\u00e7\u00f4\u00ee\u00ea\u00eb\u00ef0-9A-Za-z\s]+$/);},
		// --- cpordep : teste la validité d'un code postal / département - les valeurs commancant par 00 ou 99 sont interdites
		cpordep:function(field){if (field.value=="") return true; if((field.value.charAt(0) == 0  && field.value.charAt(1) == 0) || (field.value.charAt(0) == 9  && field.value.charAt(1) == 9)) return false; return !!field.value.match(/\d[ab0-9](\d{3})?/i);},
		// ---phonenumber :  teste la validaité d'un numéro de téléphone (10 chiffres)
		phonenumber:function(field){if (field.value=="") return true; return !!field.value.match(/^\d{10}$/);},
		// -- numbers : teste si le champ saisi ne contient que des chiffres
		numbers:function(field){if (field.value=="") return true; return !!field.value.match(/^\d+$/);},
		// -- letters : teste si le champ saisi ne contient que des lettres
		letters:function(field){if (field.value=="") return true; return !!field.value.match(/^[-\u00E9\u00e8\u00e0\u00e7\u00f4\u00ee\u00ea\u00eb\u00efA-Za-z\s]+$/);},
		letters:function(field){if (field.value=="") return true; return !!field.value.match(/^[-\u00E9\u00e8\u00e0\u00e7\u00f4\u00ee\u00ea\u00eb\u00efA-Za-z\s]+$/);}
	},
	
	// --- recapitule la totalité des messages d'erreur dispo en fonction du type d'erreur 
	errorMessages:{
		required:{
			checkbox:"Cette case doit \u00EAtre coch\u00E9e",
			radio:"Vous devez s\u00E9lectionner une de ces options",
			text:"Attention, ce champ est obligatoire",
			select:"Vous devez s\u00E9lectionner une de ces options"
			
		},
		requiredoptional:this.required,
		duo:"Une information associ\u00E9e &agrave; ce champ est manquante",
		associatedOptional:"Veuillez renseigner ce champ ou l'un des champs associ\u00E9s",
		associatedOptionalRadio:"Veuillez renseigner au moins l'un des champs ci-dessous",
		email:"Cette adresse e-mail est erron\u00E9e",
		numbers:"Ce champ ne doit comporter que des chiffres",
		letters:"Ce champ ne doit comporter que des lettres",
		phonenumber2:"Veuillez v\u00E9rifier votre num\u00E9ro de t\u00E9l\u00E9phone",
		address:"Votre adresse n'est pas valide",
		cpordep:"Ce code postal est invalide",
		date:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		dateMax:"La date doit &ecirc;tre inf&eacute;rieure &agrave; la date en cours",
		dateMax6mois:"La date de la fin de votre pr&ecirc;t doit exc&eacute;der de six mois la date du jour.",
		dateMax70ans:"Votre date de naissance n'est pas valide.",
		dateValid:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		dateValidOptional:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		inf1525:"Le montant des droits ne peut d&eacute;passer 1525 &euro;",
		dateMajeur:"Vous devez &ecirc;tre majeur pour b&eacute;n&eacute;ficier d'un pr&ecirc;t",
		maxOld25:"L'&acirc;ge de votre enfant ne doit pas d&eacute;passer 25 ans.",
		compareAge:"La diff&eacute;rence d'&acirc;ge entre vous et votre enfant doit &ecirc;tre sup&eacute;rieure &agrave; 16 ann&eacute;es."
	},
	
	// --- retourne la position du message d'erreur par rapport au champ courant, cette position peut être changé via la proprieté "position", ex : afterfield
	getMessagePosition:function(field){
		var element=field;
		var position="";
		if (field.getAttribute("position")) {
			var position = field.getAttribute("position");
			if (!position.match(/^(before|after)(label|parentnode|field)$/)) {
			 	position = formval.defaultPosition;
			}
			var arrPos = position.match(/^(before|after)(label|parentnode|field)$/);
			switch(arrPos[2]) {
				case "label" : 
					var node = field;
					while(node.nodeName!="LABEL") {
						node=node.previousSibling;
					}
					if (node.nodeName=="LABEL") element=node;
					break;
				case "parentnode" : 
					var parentPos = field.getAttribute("parentnode_pos") ? parseInt(field.getAttribute("parentnode_pos")) : 1;
					var element=field;
					for (var i=0; i<parentPos; i++) {
						element=element.parentNode;
					}					
					break;
			}
			return [arrPos[1],element];
		} else {
			return [formval.defaultPosition.match(/(before|after)(label|parentnode|field)/)[1],element]
		}
	},
	
	//---  retourne un tableau d'éléments dans le form qui ont le même nodeName, name et type
	getSameElements:function(field) { 
		var aReturnElements=[];
		var elt=field.form.elements;
		for (var i=0; i<elt.length; i++) {
			if (elt[i].nodeName==field.nodeName && elt[i].name==field.name && elt[i].type==field.type) {
				aReturnElements.push(elt[i]);
			}
		}
		return aReturnElements;
	},
	
	// ---fonction qui appelle pour chaque champ du formulaire les règles de validation associées, et gère l'affichage du message d'erreur si besoin 
	check:function(theForm, showOnlyOneMessage, otherReturnValues) {
		formval.globalErrorMsg = "";
		var scrollTop = document.body.scrollTop;
		var finalErrorMessage="";
		var hasError=false;
		// --- récupération de la totalité des champs du formulaire
		//var elm = theForm.elements;
		// Modif Geof : fonctionnement nouveau des onglets
var elm = document.forms[theForm].elements;

		for (var i=0; i<elm.length; i++) {
			var x=elm[i];
			if (x.getAttribute("validation") && x.offsetHeight && x.offsetHeight>0 && !x.disabled){
				var validOptions = x.getAttribute("validation").split(/\s+/g);
				finalErrorMessage="";
				// --- boucle sur les différentes règles de validation
				for (var j=validOptions.length-1; j>=0; j--) {
					if (typeof(formval.validationFunc[validOptions[j]])=="function") {
						// --- returnMessage contient la valeur de retour de la règle en cours
						var returnMessage = formval.validationFunc[validOptions[j]](x);
						var quantity = typeof(returnMessage)=="object" && returnMessage.length ? returnMessage[1] : 0;
						returnMessage = typeof(returnMessage)=="object" && returnMessage.length ? returnMessage[0] : returnMessage;
						if (returnMessage==false || typeof(returnMessage)=="string") { //si message erreur ou index de tableau associatif
							hasError=true;
							if (x.getAttribute(validOptions[j]+"_em")!=null) { //si le champ possede un message personnalis&eacute; pour l'erreur alors on affihce
								finalErrorMessage=x.getAttribute(validOptions[j]+"_em");
							} else { //sinon
								if (typeof(returnMessage)=="string") { //si le message d'erreur est un index de tableau associatif
									finalErrorMessage=formval.errorMessages[validOptions[j]][returnMessage]; //on va chercher le message associ&eacute; &agrave; cet index
								} else {
									if (formval.errorMessages[validOptions[j]] && typeof(formval.errorMessages[validOptions[j]])=="string") { //si le message d'error est false
										finalErrorMessage=formval.errorMessages[validOptions[j]]; //alors on retourne le message d'erreur associ&eacute;
										if (quantity>0) finalErrorMessage=finalErrorMessage.replace(/\#\#/g,quantity);
									}
									else finalErrorMessage=formval.defaultErrorMessage; //sinon on affiche le message d'erreur par d&eacute;faut pour tout champ
								}
							}
						} else {
							formval.clearMessage(x);
						}						
					}
				}
				if (finalErrorMessage!="") formval.showMessage(x, finalErrorMessage);
			}
		}
		
		
		document.body.scrollTop=scrollTop;
		var secondErrorValue=false;
		if (otherReturnValues!=null) {
			if(typeof(otherReturnValues)=="boolean") {
				secondErrorValue=!otherReturnValues;
			} else {
				for (var i=0; i<otherReturnValues.length; i++) {
					if (!otherReturnValues[i]) secondErrorValue = true;
				}
			}
		}
		
		hasError = hasError || secondErrorValue;
		if (showOnlyOneMessage) {
			if (showOnlyOneMessage==true) {
				elm = null;
			} else {
				var elm = document.getElementById(showOnlyOneMessage);
			}
			if (hasError) {
				alert(formval.globalErrorMsg);
			} else {
				if (elm) elm.className=elm.className.replace(/\berrorAlertShow\b/g,"");
			}
		}
//		alert(hasError);
		for (var i=0; i<elm.length; i++) {
			var x=elm[i];
			if(x.disabled || x.readonly){
				x.disabled = false;
			}
		}
		return (!hasError); //return true si aucune erreur sinon false;
	},

	//--- verifie si le message d'erreur doit se placer avant le champ en cours
	checkIfErrorMessageBefore:function(field) {
		var node = field;
		var i=0;
		while(node.previousSibling && i<=2) {
			if (node.nodeType==1 && node.className.match(/\berrormsg\b/))
				return node;
			node=node.previousSibling;
			i++;
		}
		return null;
	},

	// --- suppression du message d'erreur
	clearMessage:function(field) {
		if (field.getAttribute("typemessage") && field.getAttribute("typemessage")=="aspect") {
			if (field.getAttribute("rel") && field.getAttribute("rel")!="") {
				var elm = document.getElementById(field.getAttribute("rel"));
				elm.className = elm.className.replace(/\berror\b/g,"");
			}
		} else {
			if (field.associatedErrorMessage) {
				field.associatedErrorMessage.style.display="none";
			}
		}
	},
	
	// --- permet d'insèrer un node après un autre node spécifié dans le dom
	insertAfter:function(parent, nodeToInsert, nodeInDom) {
		nodeToInsert = nodeInDom.appendChild(nodeToInsert);
		return nodeToInsert;
	},
	
	// --- mise en place du message d'erreur
	showMessage:function(field, msg) {
		formval.globalErrorMsg += "- " + msg + "\n";
		if (field.getAttribute("typemessage") && field.getAttribute("typemessage")=="aspect") {
			if (field.getAttribute("rel") && field.getAttribute("rel")!="") {
				var elm = document.getElementById(field.getAttribute("rel"));
				// on ajoute la class error à l'élément
				elm.className+=" error";
			}
		} else {
			if (!field.associatedErrorMessage) {
				if (!formval.checkIfErrorMessageBefore(field)) {
					var pos = formval.getMessagePosition(field);
					var parentField = getParent(field, formval.lineInput);
					// --- récupération du node "label"
					var label = getNode(parentField, {nodeName:"label"});
					if (label)
						// --- on ajoute la zone d'erreur en créant un <span>
						var msgField = formval.insertAfter(label.parentNode, document.createElement("span"),label);
					else 
						var msgField = formval.insertAfter(parentField.parentNode, document.createElement("span"),parentField);
					msgField.className="errormsg";
					field.associatedErrorMessage=msgField;
				} else {
					field.associatedErrorMessage = formval.checkIfErrorMessageBefore(field);
				}
			}
			field.associatedErrorMessage.innerHTML=msg;
			field.associatedErrorMessage.style.display="";	
		}
	}
}


// fonction de desactivation de champs : 
// -- le param fieldsTo est un array qui cvontient les id des champs à activer/désactiver
// -- le param toggle indique si on active ou si l'on desactive les champs ( valeur 0 ou 1 )
// -- le param fieldsToClear indique les champs que l'on doit vider
function toggleDisabled(fieldsTo, toggle, fieldsToClear){
	for( var j=0; j<fieldsTo.length; j++){  
		if(parseInt(toggle) == 1){ 
			document.getElementById(fieldsTo[j]).disabled = true;
			for(var i=0; i<fieldsToClear.length; i++) document.getElementById(fieldsToClear[i]).value = '';
		}else document.getElementById(fieldsTo[j]).disabled = false;
	}
}


//fonction permettant l'apparition des champs "enfants" de l'onglet 1 du formulaire
// -- le param numberOfChildren indique le nombre de champs "enfants" que l'on veut afficher
// -- le param maxChildren indique le nombre d'enfants max   
function makeChildrenVisible(numberOfChildren, maxChildren){
	for(var i=0; i<maxChildren; i++){ 
		if(i<numberOfChildren) document.getElementById("enfant"+(i+1)).style.display = "block";
		else document.getElementById("enfant"+(i+1)).style.display = "none";
	}
}


//clean les valeurs (retire les 0 en début de chaine)  passées en paramètre
function clean0(field){
	valeur = field.value;
	
	var cpt=0;
	var tmp="";
	var bool=true;
	
	while(cpt<valeur.length){
		if(valeur.charAt(cpt) != 0 || bool==false){ 
			tmp+=valeur.charAt(cpt);
			bool=false;
		}
		cpt++
	}
	
	field.value = tmp;
}


//fais la somme des valeurs passées dans le tableau fieldsFrom, et envoie le résultat dans le champ fieldTo
function makeSum(fieldsFrom, fieldTo ){
	var somme = 0;
	
	for( var i=0; i<fieldsFrom.length; i++ ){ 
		if(document.getElementById(fieldsFrom[i]).value != '') somme += parseInt(document.getElementById(fieldsFrom[i]).value);
	}
	
	if(isNaN(somme) == false ) document.getElementById(fieldTo).value = somme;
}


//fonction utilisée dans le step 4 = > permet d'obtenir le total net annuel (salaire annuel emprunteur * nbre mois emprunteur + salaire annuel co-emprunteur * nbre mois co-emprunteur )
//Ne renvoie pas le résultat si le produit est NaN (lettre entrées dans un champ par exemple...) 
function makeTotal(fieldsFrom, fieldTo){
	var somme = 0;
	var beware = false;
	
	for( var i=0; i<fieldsFrom.length; i+=2 ){ 
		if(isNaN(parseInt(document.getElementById(fieldsFrom[i]).value)*parseInt(document.getElementById(fieldsFrom[i+1]).value)) == false){
			somme += parseInt(document.getElementById(fieldsFrom[i]).value)*parseInt(document.getElementById(fieldsFrom[i+1]).value);
		}
	}
	
	if(beware == false) document.getElementById(fieldTo).value = somme;
}
