
/*---------------------- f o r m c h e c k -------------------------#
#																	#
#					   release 1.4 -- 010606						#
# 						 editor: |-storm-|							#
#				modifiziert 011114 für diplomarbeit.de				#
#																	#
#	javascriptbasierte validierung von formularen in html.			#
#	getestet für: ns4x, ns6, ie5x									#
#																	#
#	features: 														#
#	- gezielte referenz des formulars (auch bei mehreren <form>'s)	#
#	- automatisches erkennen validierbarer felder					#
#	- validierung von formell gültigen email-addressen 				#
#	- validierung von bundesdeutschen postleitzahlen				#
#	- parametergesteuerte prüfung von textfeldern, textarea			#
#	- per default müssen alle felder ausgefüllt werden				#
#	- felder über parameter als "optional" deklarieren				#
#	- validierung von checkbox, radio, select						#
#	- automatisches generieren einer alert-fehlermeldung			#
#	- autocaseconvert für fehlermeldungen (name -> Name)			#
#																	#
#																	#
#	einbindung in html:												#
#																	#
#	das zu validierende formular hat im <form> tag die parameter	#
#	-	<form name="foo" onsubmit="return formcheck('foo')">		#
#	(plus andere parameter, z.b. action und method).				#
#																	#
#	die parameter für die validierung werden im head der html 		#
#	als objekt angegeben: 											#
#	-	<!--														#
#	-		var fooparam=new Object;								#
#	-		fooparam.feld1='a-';									#
#	-		fooparam.irgendwas='a-';								#
#	-		fooparam.nochwas='0';									#
#	-		fooparam.mailtextfeld='email';							#
#	-	//-->														#
#	dabei ist es relevant, daß der name des objektes vom 			#
#	formularnamen abgeleitet wird. (die parameter für das formular	#
#	'foo' werden im objekt 'fooparam' gespeichert.)					#
#																	#
#	DAS PARAMETEROBJEKT IST ZWINGEND ERFORDERLICH.					#
#																	#
#	die syntax für die parameter: 									#
#	0		macht ein feld optional (default ist "pflichtfeld")		#
#	weitere spezifikation für text (text, textarea, password):		#
#	a		buchstaben sind zulässig								#
#	1		ziffern sind zulässig									#
#	-		bindungen sind zulässig									#
#	@		emailtypische zeichen sind zulässig						#
#	email	verlangt eine valide emailaddresse nach xx@xx.xx		#
#	plz		verlangt eine deutsche postleitzahl 					#
#	die parameter können - bis auf 'email' und 'plz' - kombiniert 	#
#	werden; fooparam.Firma='a-0' ist ein optionales Feld, das 		#
#	(wenn es ausgefüllt wird) buchstaben und bindungen enthalten 	#
#	darf - bei nicht validen einträgen kommt der alert				#
#	'Firma: Bitte geben Sie nur Buchstaben und Bindungen ein.'		#
#																	#
#	im formular selbst sollten die felder in sauberem deutsch 		#
#	benannt sein, da der feldname für das generieren des alert 		#
#	verwendet wird. 												#
#	bei select-feldern, die nicht optional sind, muß die erste 		#
#	option den value="default" haben. 								#
#																	#
#																	#
#	forthcoming features: 											#
#	- optionale englischsprachige fehlermeldungen					#
#	- kombinierbarkeit der parameter 'plz', 'email' mit '0'			#
#	- detailliertere validierung der domain bei 'email'				#
#	- detailliertere parameter für die textfelder 					#
#	  (z.b. groß- und kleinbuchstaben)								#
#	- parameterobjekt nicht zwingend erforderlich					#
#																	#
#------------------------------------------------------------------*/

function formcheck(formname) 
{

/*------------------------------------------------------------------#
#					initialisieren von variablen					#
#------------------------------------------------------------------*/

	var satz,loopcount,character,charnr,cstart,cend,formcount,felder,fehler;

	//zurücksetzen und initialisieren des arrays, das für die prüfung der radiobuttons notwendig ist:
	radioarray='';
	radioarray=new Array();
	radioarray[0]=new Array(3);
	//zurücksetzen und initialisieren des fehler-arrays
	fehler=new Array();
	//zurücksetzen und initialisieren von variablen für die while-schleife:
	felder=eval('window.document.'+formname+'.length');
	loopcount=0;
	formcount=0;

/*------------------------------------------------------------------#
#						globale parameter							#
#------------------------------------------------------------------*/

	//zeichengruppen für die textfeldüberprüfung:
	buchstaben="abcdefghijklmnopqrstuvwxyzöäüßABCDEFGHIJKLMNOPQRSTUVWXYZÖÄÜ";
	ziffern="1234567890";
	bindungen=" -/().+&";
	zeichen="@._\n€!§$%&/()=?`´^°-.,_:;+*<>{[]}\²³µ~#'"+'"';

	//formularelemente, die nicht überprüft werden:
	nocheck='button,submit,reset,fileupload,hidden';
	
/*------------------------------------------------------------------#
#						beginn der prüfroutine						#
#																	#
#	in einer while-schleife wird jedes element des formulars 		#
#	verarbeitet, abhängig vom typ.									#
#																	#
#------------------------------------------------------------------*/

	while (loopcount<felder)
	{
		feldname=eval('window.document.'+formname+'.elements['+loopcount+'].name');
		feldtype=eval('window.document.'+formname+'.elements['+loopcount+'].type');
		feldwert=eval('window.document.'+formname+'.elements['+loopcount+'].value');
		(eval(formname+'param'))&&feldname?feldparam=eval(formname+'param.'+feldname):feldparam='_error';
		if(!feldparam)feldparam='_error';
		if(feldtype.indexOf('select')!=-1)feldtype='select';
		if(feldtype=='textarea'||feldtype=='password')feldtype='text';
		if(nocheck.indexOf(feldtype)==-1)
		{
			fehlermeldung='';
			// ----- unterscheidung zwischen feldtypen ---------------------------------
			switch (feldtype)
			{

/*------------------------------------------------------------------#
#					verarbeiten von textfeldern						#
#------------------------------------------------------------------*/

				case 'text': 
				{
					switch (feldparam)
					{
						/*zuerst wird geprüft, ob auf das textfeld eine sonderregelung (z.b. email) applizierbar ist (parameter='email'). um neue sonderregelungen zu etablieren, muss der entsprechende case 'sonderregelung': eingerichtet werden und im head der spezifischen datei der entsprechende parameter formularparam.feldname='sonderregelung' gesetzt werden.*/
						case 'email':
						{
							index_a = feldwert.indexOf('@') ;
							index_dot = feldwert.lastIndexOf('.');
							value_l = feldwert.length;
							if (feldwert=='' || index_a < 1 || index_dot == -1 || (value_l - index_dot) < 3 || (value_l - index_dot) > 4 || (index_dot - index_a) < 3)
							{
								fehler[loopcount]=new Array(2);
								fehler[loopcount][0]=feldname;
								fehler[loopcount][1]="Sie müssen eine gültige EMail-Adresse eingeben.";
							}
							break;
						}
						case 'plz':
						{
							if (feldwert.length != 5)
							{
								fehler[loopcount]=new Array(2);
								fehler[loopcount][0]=feldname;
								fehler[loopcount][1]="Sie müssen eine gültige Postleitzahl eingeben.";
							} else 
							{
								formlaenge=feldwert.length;
								charnr=0;
								for (charnr; charnr<formlaenge; charnr++) 
								{
									character=feldwert.charAt(charnr);
									if (ziffern.indexOf(character)== -1) 
									{
										fehler[loopcount]=new Array(2);
										fehler[loopcount][0]=feldname;
										fehler[loopcount][1]="Sie müssen eine gültige Postleitzahl eingeben.";
										break;
									}
								}
							}
							break;
						}
						default:
						{
							/* wenn die parameter für ein textfeld keinen sonderfall beschreiben, wird ein zeichensatz anhand der parameter generiert: */
							satz='';
							fehlermeldung='';
							fehlermeldung=new Array();
							fehlerlength=fehlermeldung.length;
							if (feldparam.indexOf('a')> -1)
							{
								fehlerlength=fehlermeldung.length;
								fehlermeldung[fehlerlength]='Buchstaben';
								satz=satz.concat(buchstaben);
							}
							if (feldparam.indexOf('1')> -1)
							{
								fehlerlength=fehlermeldung.length;
								fehlermeldung[fehlerlength]='Ziffern';
								satz=satz.concat(ziffern);
							}
							if (feldparam.indexOf('-')> -1)
							{
								fehlerlength=fehlermeldung.length;
								fehlermeldung[fehlerlength]='Bindungen';
								satz=satz.concat(bindungen);
							}
							if (feldparam.indexOf('@')> -1)
							{
								fehlerlength=fehlermeldung.length;
								fehlermeldung[fehlerlength]='Zeichen';
								satz=satz.concat(zeichen);
							}
							// der computer textet uns jetzt mal eben die fehlermeldung in sauberem deutsch:
							switch (fehlerlength)
							{
								case '0':
								{
									fehlermeldung=fehlermeldung[0];
									break;
								}
								case '1':
								{
									fehlermeldung=fehlermeldung[0]+' und '+fehlermeldung[1];
									break;
								}
								case '2':
								{
									fehlermeldung=fehlermeldung[0]+', '+fehlermeldung[1]+' und '+fehlermeldung[2];
									break;
								}
								case '3':
								{
									fehlermeldung=fehlermeldung[0]+', '+fehlermeldung[1]+', '+fehlermeldung[2]+' und '+fehlermeldung[3];
									break;
								}
							}
							fehlermeldung='Geben Sie bitte nur '+fehlermeldung+' ein.';
							// wenn keine parameter für das textfeld angegeben sind, sind alle zeichen verfügbar:
							if (satz=='')satz=buchstaben+ziffern+zeichen+bindungen;
							// -------- feldwert überprüfen -----------------------------
							formlaenge=feldwert.length;
							charnr=0;
							if (feldwert==''&&feldparam.indexOf('0')==-1)
							{
								fehler[loopcount]=new Array(2);
								//diplomarbeit: optionaler feldname im parameterobjekt
								eval(formname+'param.'+feldname+'_n')?fehler[loopcount][0]=eval(formname+'param.'+feldname+'_n'):fehler[loopcount][0]=feldname;
								fehler[loopcount][1]=fehlermeldung;
								if(feldparam=='_error') fehler[loopcount][1]='Bitte machen Sie eine Eingabe.';
							} else
							{
								for (charnr; charnr<formlaenge; charnr++) 
								{
									character=feldwert.charAt(charnr);
									if (satz.indexOf(character)== -1) 
									{
										fehler[loopcount]=new Array(2);
										fehler[loopcount][0]=feldname;
										fehler[loopcount][1]=fehlermeldung;
										break;
									}
								}
							}
							break;
						}
						break;
					}
					break;
				}

/*------------------------------------------------------------------#
#					verarbeiten von radio buttons					#
#	bei den radio-buttons erfolgt die auswertung erst später, da	#
#	mehrere radio-buttons den gleichen namen tragen können/müssen.	#
#------------------------------------------------------------------*/

				case 'radio':
				{
					feldcheck=eval('window.document.'+formname+'.elements['+loopcount+'].checked');
					radiolength=radioarray.length;
					//erstmalige initialisierung des radioarray, wenn noch keine radiobutton-gruppe angelegt ist:
					if (!radioarray[0][0])
					{
						radioarray[0][0]=feldname;
						//wenn die radiobutton-gruppe den parameter 'optional' hat, wird '_0' als grundwert eingesetzt;
						//ansonsten wird '_error' eingesetzt:
						feldparam=='0'?radioarray[0][1]='_0':radioarray[0][1]='_error';
						//wenn der radiobutton aktiviert ist, wird sein wert in das array eingetragen:
						if(feldcheck==true)radioarray[0][1]=feldwert;
						radioarray[0][2]=loopcount-1;
					} else
					{
						/*in einer schleife wird geprüft, ob es schon ein array für die radiobutton-gruppe gibt.
						  wenn es das array schon gibt, wird bei aktivem radiobutton der wert eingetragen.
						  wenn es das array noch nicht gibt, wird ein neues angelegt analog zur erstmaligen initialisierung. */
						radiocount=0;
						while(radiocount<radiolength)
						{
							if(radioarray[radiocount][0]==feldname)
							{
								if (feldcheck==true)radioarray[radiocount][1]=feldwert;
								break;
							}
							radiocount++;
						}
						if(radiocount==radiolength)
						{
							radioarray[radiocount]=new Array(2);
							radioarray[radiocount][0]=feldname;
							feldparam=='0'?radioarray[radiocount][1]='_0':radioarray[radiocount][1]='_error';
							if(feldcheck==true)radioarray[radiocount][1]=feldwert;
							radioarray[radiocount][2]=loopcount-1;
						}
					}
					break;
				}

/*------------------------------------------------------------------#
#					verarbeiten von checkboxen						#
#------------------------------------------------------------------*/

				case 'checkbox':
				{
					feldcheck=eval('window.document.'+formname+'.'+feldname+'.checked');
					if (feldcheck==false&&feldparam!='0')
					{
						fehler[loopcount]=new Array(2);
						fehler[loopcount][0]=feldname;
						fehler[loopcount][1]='Sie müssen dieses Feld ankreuzen.';
					}
					break;
				}

/*------------------------------------------------------------------#
#					verarbeiten von select-feldern					#
#------------------------------------------------------------------*/

				case 'select':
				{
					if (feldwert=='default'&&feldparam!='0')
					{
						fehler[loopcount]=new Array(2);
						fehler[loopcount][0]=feldname;
						fehler[loopcount][1]='Sie müssen hier eine Auswahl treffen.';
					}
					break;
				}
			}
		}
		loopcount++;
	}

/*------------------------------------------------------------------#
#		auswerten der information aus den radiobuttons				#
#------------------------------------------------------------------*/
	
/* jetzt sind alle formularfelder abgearbeitet. die radiobuttons sind 
noch nicht ausgewertet, sondern im array 'radioarray' abgelegt. wenn 
das array einen wert hat, wird es hier ausgewertet: (dabei wird jeweils 
geprüft, ob das feld radioarray[n][1] den wert '_error' hat. dieser wert 
wird bei der inialisierung jedes radioarray[n] gesetzt, wenn das feld 
nicht als optional gekennzeichnet ist.) */
	
	if (radioarray[0][0])
	{
		radiocount=0;
		radiolength=radioarray.length;
		while (radiocount<radiolength)
		{
			if (radioarray[radiocount][1]=='_error')
			{
				fehler[radioarray[radiocount][2]]=new Array(2);
				fehler[radioarray[radiocount][2]][0]=radioarray[radiocount][0];
				fehler[radioarray[radiocount][2]][1]='Sie müssen hier eine Auswahl treffen.';
			}
			radiocount++;
		}
	}
	
/*------------------------------------------------------------------#
#						ende der prüfroutine						#
#	zusammenstellen der fehlermeldung und ausgabe des 'return'		#
#------------------------------------------------------------------*/

	if (fehler.length!=0) 
	{
		fehlermeldung='Ihre Angaben sind leider nicht korrekt:\n\n';
		loopcount=0;
		fehlerlength=fehler.length;
		while (loopcount<fehlerlength)
		{
			if (fehler[loopcount])
			{
				//v1.4: erster buchstabe des feldnamens wird groß geschrieben:
				if(eval(formname+'param.caseconv')!=false)fehler[loopcount][0]=fehler[loopcount][0].substring(0,1).toUpperCase()+fehler[loopcount][0].substring(1,fehler[loopcount][0].length);
				//fehler wird ausgegeben
				//mod für diplomarbeit: wenn vorletztes zeichen _ die letzten zwei zeichen kürzen:
				fehler[loopcount][0].charAt(fehler[loopcount][0].length-2)=="_"?fehlermeldung+=fehler[loopcount][0].substr(0,fehler[loopcount][0].length-2):fehlermeldung+=fehler[loopcount][0];
				fehlermeldung+=': '+fehler[loopcount][1]+'\n';
			}
			loopcount++;
		}
		alert (fehlermeldung);
		return false;
	} else
	{
		return true;
	}
}
