/*	Versie:					1.4
	Datum:					23 mei 2005
	Auteur:					Harm van Beek / Koen Peters (C) ISAAC 	
	Backwards compatible: 	t/m versie 1.0
	Korte Beschrijving: 	JavaScript om waarden van form objecten te controleren.
	Changes: 				1.3: Het standaardgedrag is veranderd van VERWIJDER_CHECKS naar VERWIJDER_CHECKS_NIET
							1.4: Er is een nieuwe checkextension bijgekomen: _checkbox	
	Dependencies:			-

	USAGE:
	De Onsubmit van het formulier moet worden uitgebreid met een aanroep naar check(this).
	Bijv:
	<form name="formulier" action="do.jsp" method="post">
	
	Naast de verplichte eerste parameter, is er nog een tweede niet verplichte parameter die de volgende waarden mag hebben:
	VERWIJDER_CHECKS: 		Na een controle van het form waarbij geen fouten zijn gevonden worden de hidden 'controle velden' verwijderd.
	VERWIJDER_CHECKS_NIET: 	(Standaard) De hidden 'controle velden' worden nooit verwijderd.
	Deze eerste waarde is handig als een submit gaat mbv van een GET. De controlevelden komen dan niet in de URL balk te staan. Een nadeel is dat 
	de velden verwijderd zijn als er op Back wortd geklikt. De controle kan dan fout gaan.
	Deze laatste waarde is handig wanneer het form niet daadwerkelijk een post tot gevolg heeft, maar meerdere keren wordt gebruikt binnen de 
	pagina waarbij de controle telkens weer van belang is.
	
	De volgende type controles zijn mogelijk met deze methode.
	
	1)	Controles van textarea's en input velden met type 'text', 'password' en 'file' mbv reguliere expressies.
		Voor ieder te controleren veld in het formulier wordt een veld met dezelfde naam, 
		uitgebreid met _check, opgenomen in het formulier.  
		Als er meerdere checks moeten worden uitgevoerd, dan kunnen er meerdere velden met een 
		_check uitbreiding worden opgenomen. Ieder extra veld moet wel een opeenlopend volgnummer
		krijgen, te beginnen bij 1. Dus: <veldnaam>_check, <veldnaam>_check1, <veldnaam>_check2, etc
		 
		De waarde van het controle-veld = "regexp||true/false||error".
		- regexp: JavaScript reguliere expressie waaraan de ingevulde waarde moet voldoen;
		- true/false: Deze boolean waarde geeft aan of het veld leeg mag zijn;
		- error: De foutmelding die als JavaScript Alert getoond wordt indien de ingevulde waarde verkeerd is.

	2)	Controles van textarea's en input velden met type 'text', 'password' en 'file' mbv externe functies.
		Voor ieder te controleren veld in het formulier wordt een veld met dezelfde naam, 
		uitgebreid met _function, opgenomen in het formulier.  
		Als er meerdere checks moeten worden uitgevoerd, dan kunnen er meerdere velden met een 
		_function uitbreiding worden opgenomen. Ieder extra veld moet wel een opeenlopend volgnummer
		krijgen, te beginnen bij 1. Dus: <veldnaam>_function, <veldnaam>_function1, <veldnaam>_function2, etc
		 
		De waarde van het controle-veld = "functienaam()||error".
		- functienaam(). De functie die moet worden aangeroepen over het veld. 
			o	Wanneer de waarde van het veld moet worden meegegeven aan de functie, dan kan dat door op de plek waar dat moet 
				gebeuren de waarde _value_ te zetten. De waarde van het veld wordt hier dan voor _value_ gesubstitueerd.
		  		bv functienaam(_value_), of functienaam('_value_', TRUE, 1).
			o	Wanneer het id van het veld moet worden meegegeven aan de functie, dan kan dat door op de plek waar dat moet 
				gebeuren de waarde _id_ te zetten. Het id van het veld wordt hier dan voor _id_ gesubstitueerd.
		  		bv functienaam(_id_), of functienaam('_id_', TRUE, 1).						  
			o	Wanneer de naam van het formulier moet worden meegegeven aan de functie, dan kan dat door op de plek waar dat moet 
				gebeuren de waarde _formName_ te zetten. De baan van het veld wordt hier dan voor _formName_ gesubstitueerd.
		  		bv functienaam(_formName_), of functienaam('_formName_', TRUE, 1).						  

		- error: De foutmelding die als JavaScript Alert getoond wordt indien de ingevulde waarde verkeerd is.

	3)	Controles van input velden van type 'radio'.
		Voor iedere te controleren radiogroup (dus niet per radiobutton) in het formulier 
		wordt een veld met dezelfde naam, uitgebreid met _radio, opgenomen in het formulier.  
	
		De waarde van het controle-veld = "true/false||error".
		- true/false: Deze boolean waarde geeft aan of de radiogroup geen enkel geselcteerde radiobutton mag hebben (leeg is).
		- error: De foutmelding die als JavaScript alert getoond wordt indien de group leeg is terwijl dit niet mag.

	4)	Setten van velden aan de hand van de status van checkboxen. 
		Voor iedere checkbox in het formulier wordt een veld met dezelfde naam, uitgebreid met _set, opgenomen in het formulier.  
		Aan de hand van de waarde van dit _set veld wordt een ander veld voorzien van een waarde.
		Het voordeel van deze methode is dat er ook een waarde wordt gestuurd als de checkbox niet is afgevinkt. 
	
		De waarde van het controle-veld = "veldnaam||waarde als afgevinkt||waarde als niet afgevinkt".
		- veldnaam: De naam van het formobject waarvan de value moet worden ingesteld.
		- waarde als afgevinkt: De value dat het veld moet aannemen als de checkbox is afgevinkt.
		- waarde als niet afgevinkt: De value dat het veld moet aannemen als de checkbox niet is afgevinkt.

	5)	Controleren of een checkbox is aangevinkt.
		Voor iedere checkbox in het formulier die moet worden aangevinkt wordt een veld met dezelfde naam, uitgebreid met _checkbox, 
		opgenomen in het formulier. Wanneer de checkbox niet is aangevinkt, dan wordt er een fourmelding gegeven.
	
		De waarde van het controle-veld = "error".
		- error: De melding die moet woren weergegeven als de checkbox niet is aangevinkt.


	Standaard is het karakter waarop wordt gesplit ||, maar dar kan ook worden veranderd, door in de pagina een andere waarde op
	te nemen. 
	Bijv:
	<script type="text/javascript">var splitter = '-!-'</script>
	
	Wanneer een veld een verkeerde waarde bevat, dan krijgt dat veld de focus na het afbeelden van de foutmelding.
*/

var splitter				= "||";
var checkextension			= "_check";
var setextension			= "_set";
var radioextension			= "_radio";
var checkboxextension		= "_checkbox";
var functionextension		= "_function";

var VERWIJDER_CHECKS_NIET	= false;
var VERWIJDER_CHECKS		= true;

var errorElem				= null;
var inputelements			= null;
var verwijderChecks 		= VERWIJDER_CHECKS_NIET;

function check(inputform, verwChecks) {
	verwijderChecks = verwChecks == null? verwijderChecks: verwChecks;
    errorElem		= null;
	inputelements	= inputform.elements;
	// doorloop alle niet hidden elementen van het inputform
	// zodra er iets fout gaat, stoppen. Er wordt dus maar 1 melding gegeven.
	var errorFound = false;
	var i=0;

	while (!errorFound && i<inputelements.length) {
		// element is het huidige element
		var element = inputelements[i];
		if (element.type != 'hidden') {
			// CONTROLE OP _CHECK, _CHECK1, ETC
			// kijk of het element gecontroleerd moet worden door een check (_CHECK)
			if (getElementByHash(element.name, checkextension) != null) {
				// bepaal de waarde van het veld in check en splits het bij de spitter (standaard ||)
				var teller = 0;			
				while (!errorFound && getElementByHash(element.name, checkextension + (teller>0? teller: "")) != null) {
					var checkvalue = getElementByHash(element.name, checkextension + (teller>0? teller: "")).value.split(splitter);
					if (checkvalue.length == 3) {
						// regexp wordt alles voor de eerste ||
						var regexp = new RegExp(checkvalue[0]);
						// empty wordt de boolean waarde tussen de ||'s
						var empty = eval(checkvalue[1]);
						// error alles na de laatste ||
						var error = checkvalue[2];
						if ((!empty && element.value == "") || (element.value != "" && !regexp.test(element.value))) {
							alert(error);
							errorElem = element;
							errorFound = true;
						}
					} else {
						errorFound = true;
						alert("(1) Er zit een fout in de controle van het formulier.\nVeld met waarde '" + checkvalue + "' voldoet niet aan het formaat.");
					}
					teller++;
				} // while
			}
	
			// CONTROLE OP _RADIO
			// kijk of het element gecontroleerd moet worden door een check
			if (getElementByHash(element.name, radioextension) != null) {
				// bepaal de waarde van het veld in check en splits het bij de splitter (standaard ||)				
				var checkvalue = getElementByHash(element.name, radioextension).value.split(splitter);
				if (checkvalue.length == 2) {
					var empty = eval(checkvalue[0]);
					var error = checkvalue[1];
					if (!empty) {
						var checked = false;
						var j = 0;
						var N = getElementByHash(element.name).length;
						while (!checked && j < N) {
							checked = getElementByHash(element.name)[j++].checked;
						}
						if (!checked) {
							alert(error);
							errorElem = element;
							errorFound = true;
						}
					}
				} else {
					errorFound = true;
					alert("(2) Er zit een fout in de controle van het formulier.\nVeld met waarde '" + checkvalue + "' voldoet niet aan het formaat.");
				}
			}
	
			// CONTROLE OP _SET
			// Kijk of er een element gezet moet worden (dit element is dan een checkbox)
			// Te zetten veld wordt alles voor de eerste splitter (standaard ||).
			// Als checkbox is afgevinkt dan de waarde tussen de splitters.
			// Als checkbox niet afgevinkt, dan alles na de laatste splitter.
			if (getElementByHash(element.name, setextension) != null) {
				// bepaal de waarde van het veld in set en splits het bij de ||'s
				var setvalue = getElementByHash(element.name, setextension).value.split(splitter);
				if (setvalue.length==3) {
					getElementByHash(setvalue[0]).value = setvalue[element.checked? 1: 2];
				} else {
					errorFound = true;
					alert("(3) Er zit een fout in de controle van het formulier.\nVeld met waarde '" + setvalue + "' voldoet niet aan het formaat.");
				}
			}

			// CONTROLE OP _FUNCTION, _FUNCTION1, ETC
			// kijk of het element gecontroleerd moet worden door een function (_FUNCTION)
			if (getElementByHash(element.name, functionextension) != null) {
				// bepaal de waarde van het veld in check en splits het bij de spitter (standaard ||)
				var teller = 0;			
				while (!errorFound && getElementByHash(element.name,functionextension + (teller>0? teller: "")) != null) {
					var checkvalue = getElementByHash(element.name, functionextension + (teller>0? teller: "")).value.split(splitter);
					if (checkvalue.length == 2) {
						// func wordt alles voor de eerste ||
						v = element.value.replace(/'/, '\\\'') // escapen van '						
						var func = checkvalue[0].replace(/_value_/, v).replace(/_id_/, element.id).replace(/_formName_/, inputform.name);
						// error alles na de laatste ||
						var error = checkvalue[1];
						try {
							if (!eval(func)) {
								alert(error);
								errorElem = element;
								errorFound = true;
							}
						} catch (e) { }
					} else {
						errorFound = true;					
						alert("(4) Er zit een fout in de controle van het formulier.\nVeld met waarde '" + checkvalue + "' voldoet niet aan het formaat.");
					}
					teller++;
				} 
			} 

			// CONTROLE OP _CHECKBOX
			if (getElementByHash(element.name, checkboxextension) != null) {
				var error = getElementByHash(element.name, checkboxextension).value;
				if (error) {
					if (!element.checked) { 
						alert(error);
						errorElem = element;
						errorFound = true;
					}
				} else {
					errorFound = true;
					alert("(5) Er zit een fout in de controle van het formulier.");
				}
			}
			
		} // if
		i += 1;			
	} // while
	
	// Als er geen foutmelding gevonden is, verwijder dan alle controle-velden
	// uit de te versturen waarden.
	if (!errorFound && verwijderChecks) {
		// bepaal de lengte van de checkextension
		var l = checkextension.length;
		for (var i=0; i<inputelements.length; i++) {
			var name = inputelements[i].name;
			// bepaal waar de substring checkextion voorkomt in de naam;
			var location = name.lastIndexOf(checkextension)
			if (location > -1 && location==name.length-l) {
				inputelements[i].name="";
				inputelements[i].value="";
			}
		}
	}
	
	// De focus zetten op het veld dat de fout veroorzaakte
	if (errorElem !=  null) {
		try {
			errorElem.focus();
		} catch (ex) {
			// Focus kon niet worden gezet. Laat dan maar.
		}
	}
	return !errorFound;
}



/*	Helperfunctie van de check() functie. Geeft het formelement object terug aan de hand van de naam van een formelement. 
	De naam wordt opgebouwd door 'name' en 'extension' te concateneren.
	@param name			De naam van een bestaand formelement
	@param extension	(Optioneel) Een postfix die echter de naam wordt geplaatst.
*/ 
function getElementByHash(name, extension) {	
	extension = !extension? '': extension; // Aangezien extension een optionele parameter is, even vullen met een lege string.
	
	if (inputelements[name]) {
		// In 99% van de gevallen kan het op deze manier.
		return inputelements[name + extension];
	} else {
		// Dit formulier is waarschijnlijk on the fly opgebouwd. IE wil dan nog wel eens de elements object verkeerd opbouwen, 
		// waardoor de elementen niet mbv een hash kunnen worden gevonden. vandaar deze workaround.
		k = 0;
		while (k < inputelements.length) {
			if (inputelements[k].name == name + extension) {
				return inputelements[k];
			}
			k++;
		}
		return null;
	}
}

function check_stat(inputform, sitestat, scheme) {
	if (check(inputform)) {
		if (sitestat!='null') {
		  	sitestatForm(inputform, scheme+'://nl.sitestat.com/primeline/primeline/s?'+sitestat,'');
		}
	}
	return false;
}