Verfasst von: bletra | 17. November 2009

JavaScript: Validierung als Objectschablone

Im letzten Artikel habe ich ausführlich die barrierefreie Ausgabe von falschen Benutzereingaben eines Formulars beschrieben. Nun möchte ich diese Funktionen in eine Objektschablone schieben, um sie in anderen Projekten leichter verwenden zu können. Dazu sollten möglichst wenige hard-coded Eigenschaften in dem Validatorobjekt selbst sein. Im Konstruktor übergeben wir die absolut notwendigen Parameter, nämlich

  • die id des Containers, in dem das zu validierende Formular ist (und in den die Fehlermeldung geschrieben werden soll)
  • ein Array mit den Feldern:
    • ref: id des zu validierenden Feldes
    • datamask: regulärer Ausdruck für gültige Eingaben
    • msg: Fehlermeldung

Weitere Eigenschaften werden als Public zur Verfügung gestellt, so dass sie verändert werden können. Für die es aber sinnvolle Default-Einstellungen gibt. Hard-coded bleibt die HTML-Struktur der Fehlermeldungen: h2-Überschrift mit ol-Fehlermeldungen.

Zunächst schieben wir die Funktion NewElement in unser DomHelper-Objekt. Und schreiben dann die Validator-Klasse.

function UBTValidator(containerId, validationConfig) {
	/* private */
	var ERROR_TAG_ID = "errorMessageUBT"; //should serve as a constant, but JS does not differ between vars and consts
	var ERROR_HEADER_ID = "errorNameUBT";
	var self = this; //needed for private functions like showErrors
	function showErrors(errorIndices) {
		var container, errorMsg, el, ol, li, anchor;
		container = document.getElementById(containerId);
		// we might have to reset the error messages
		if  (document.getElementById(ERROR_TAG_ID)) {
			container.removeChild(document.getElementById(ERROR_TAG_ID));
			for (i = 0;i < validationConfig.length;i++) {
				var node = document.getElementById(validationConfig[i].ref);
				if (node && node.className === self.ErrorClass) {
					node.className = "";
				}
			}
		}
		//create error intro
		errorMsg = UBTDomHelper.NewElement("div",{id:ERROR_TAG_ID});
		el = UBTDomHelper.NewElement("h2");
		el.appendChild(UBTDomHelper.NewElement("a",{id:ERROR_HEADER_ID},self.ErrorIntro));
		errorMsg.appendChild(el);
		ol = UBTDomHelper.NewElement("ol");
		//add the errors
		for (var i = 0; i<errorIndices.length; i++) {
			el = UBTDomHelper.NewElement("li");
			anchor = UBTDomHelper.NewElement("a",{href:"#"+validationConfig[errorIndices[i]].ref},validationConfig[errorIndices[i]].msg);
			anchor.onclick = function(){document.getElementById(this.href.split("#")[1]).focus();return false;}; //this is related to the context, when the link is clicked, i.e. the a-tag itself      
			el.appendChild(anchor);
			ol.appendChild(el);
			if (document.getElementById(validationConfig[errorIndices[i]].ref)) {
			  document.getElementById(validationConfig[errorIndices[i]].ref).className = self.ErrorClass;
			}  
		}
		errorMsg.appendChild(ol);
		//add everything at once to avoid confusing rereading of some screenreaders.
		if (this.FormId) {
			container.insertBefore(errorMsg, document.getElementById(this.FormId));
		}
		else {
			//fetch the first form
			container.insertBefore(errorMsg,container.getElementsByTagName("form")[0]);
		}
		document.getElementById(ERROR_HEADER_ID).focus();
	}
	
	/* public */
	this.ErrorClass = "error"; //invalid input fields will get this class
	this.ErrorIntro = "Das Formular kann leider nicht versendet werden, bitte korrigieren Sie folgende Fehler:"; //introduction of the detailed error message
	this.FormId = null; //id of the form to be validated, if not given, we take the first form of the containerId
	/** 
	  * return true on success
	  * return false otherwise and give a detailed error message (added to the document as h2 and ol)
	  */ 
	this.IsValid = function() {
		var errorIndices = [];
		for (var i in validationConfig) {
			var inputField = document.getElementById(validationConfig[i].ref)
			if (!validationConfig[i].datamask.test(inputField.value)) {
			  errorIndices[errorIndices.length] = i;
			}
		}
		if (errorIndices.length > 0) {
			showErrors(errorIndices);
			return false;
		}
		return true;  
	}
}

In Zeile 6 bedienen wir uns einen verbreiteten Tricks: Die public Eigenschaft self zeigt auf die aktuelle Instanz. Erst dadurch erhalten wir in der privaten Methode showErrors Zugriff auf this.ErrorClass und andere, also auf die öffentlichen Eigenschaften der Objektschablone. Der Rest ist ohne besondere Feinheiten 😉

 

Im zu validierenden HTML-Formular brauchen wir dann nur noch:

<script src="UBTDomHelper.js" type="text/javascript"></script>
	<script src="UBTValidator.js" type="text/javascript"></script>
	<script type="text/javascript">
		window.onload = ini;
		var validationConfig = [
			{ref:'name',datamask:/^[\.]+$/,msg:'Der Name ist erforderlich.'},
			... wie gehabt ...
		]
		var validator = null;
		function ini()
		{
			validator = new UBTValidator("formContainer", validationConfig);
			document.getElementById("Bestelldaten").onsubmit = function(){
				return validator.IsValid();
			};
		}
	</script>
Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

Kategorien

%d Bloggern gefällt das: