bgx:components logo
© 2004 -2005
Bernhard Gaul



Application Model : Validating TextInput Fields using Regular Expressions
Flash MX 2004

The following shows an approach to a generic TextInput validation model that allows you to define an arbitrary set of Regular Expression validations in an external XML file and then register TextInput fields for any of the defined validation types. Validation is triggered automatically on focusOut, you can also validate all registered fields e.g. when you hit a submit button.

Note that while the model shown may be useful in many cases as-is, it is foremost a means to demonstrate how to set up external definitions, use Regular Expressions, bind validations to TextInput fields and set styles on those fields. You may want to change the styles approach or need the focusOut event for other things and therefore prefer another approach.

The following sample uses the Regular Expression class by Pavils Jurjans which are not included in the download package. You need to download the RegExp_JLott.zip file from Pavils' site which contains the AS 2.0 version of the class and copy the RegExp.as file into the folder where you find the regexValidate.fla file.

The Working Sample

The Validation Definitions

The definitions for this example reside in an XML file called validations.xml with the following content

Resources

Download the source file
(ZIP file, 161 kB)

Regular Expression class by Pavils Jurjans
You need to download the RegExp_JLott.zip file for this example

History

2006-05-21:
Version 1.0.1, changes:
- made validate() a public function that returns a boolean - true if the field is valid
- changed valisateAll() to return a boolean, true if all fields are valid

 
<?xml version="1.0" encoding="utf-8" ?>
<validations>
<validation type="username"
regExp = "^.{3,15}$"
description = "- Username: Min 3 characters. Max 15 characters"
/>
<validation type="password"
regExp = "^[a-zA-Z]{1}[\w]{3,7}$"
description = "- Password: Only alphanumeric characters and underscores. Must start with letter. Must have between 4 and 8 characters"
/>
<validation type="email"
regExp = "^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$"
description = "- Email address not valid."
/>
</validations>

As you see each validation has a type definition, a regular expression and a description.

Note: If you define the regular expresions in an XML file you can write them just as described here. The way XML information is parsed in Flash the \ characters will be preserved. If you want to define a regular expression string in your ActionScript code, however, you have to escape all \ like \\ otherwise Flash will not interpret them as literals.

Code for the Example on this Page

For this example a class called bgx.BgxTextValidation was created to handle all field registration and validation with the following public properties and methods:

validationsXMLsrc:String The string identifying the XML file with the definitions
msgTextBox:Object An instance of a TextField|TextArea|Label|TextInput used to display the descriptions in case a field is invalid
registerField(tbx:TextInput,validationType:String):Void Method to register a TextInput field for the specified validation type.
validate(tbx:TextInput,validationType:String):Boolean Method that allows to validate individual textboxes. Returns true if valid.
validateAll():Boolean Method to validate all registered fields at once. Returns true if all fields are valid

The sample code for the FLA goes as follows:


//import the class
import bgx.BgxTextValidation; var validator:BgxTextValidation = new BgxTextValidation(); validator.msgTextBox = tbMsgInvalid; validator.validationsXMLsrc = "validations.xml"; //register the fields for validation validator.registerField(tbPassword,"password"); validator.registerField(tbUsername,"username"); validator.registerField(tbEmail,"email"); btnSubmit.onRelease = function() { validator.validateAll(); }

The BgxTextValidation Class

Finally that's the class code:

import mx.controls.TextInput;
import RegExp;
import mx.utils.Delegate;

class bgx.BgxTextValidation
{
	private var __validations:Object;
	private var __invalidArray:Array = new Array();
	private var __validationsXML:XML;
	private var __validationsXMLsrc:String;
	private var __tbMsgInvalid:Object;
	private var __fields:Object = new Object();

	//constructor 
	function BgxTextValidation()
	{}
	
	//loading definitions
	private function loadValidationsXML(xmlSource):Void
	{
		//load xml from external file
		__validationsXML = new XML();
		__validationsXML.ignoreWhite = true;
		__validationsXML.onLoad = Delegate.create(this,createValidationsHash);
		__validationsXML.load(xmlSource);
		
	}
	
	private function createValidationsHash():Void
	{
		__validations = new Object();
		var validations = __validationsXML.firstChild.childNodes;
		for (var i = 0; i < validations.length; i++)
		{
			var validation = new Object();
			validation["type"] = validations[i].attributes.type;
			validation["regExp"] = validations[i].attributes.regExp;
			validation["description"] = validations[i].attributes.description.split("\\n").join(newline);
			__validations[validations[i].attributes.type] = validation;
		}
	}
	//end loading definitions
	
	//function to register fields for validation types
	public function registerField(tbx:TextInput,validationType:String):Void
	{
		__fields[tbx] = validationType;
		tbx.addEventListener("focusOut", Delegate.create(this,function(){validate(tbx,validationType);}));
	}
	
	//check if valid
	public function validate(tbx:TextInput,validationType:String):Boolean
	{
		var validation = __validations[validationType];
		var valid = true;
		//match string 		
		if (typeof validation.regExp != "undefined" && validation.regExp != "")
		{
			var regExp = new RegExp(validation.regExp,"");
			var inputStr = tbx.text;
			valid = regExp.test(inputStr)
		}
		registerInvalid(tbx,!valid);
		setMessage();
		return valid;
	}
	
	//register if valid or not
	private function registerInvalid(tbx:TextInput,invalid:Boolean):Void
	{
		if (invalid)
		{
			//don't register the same field twice
			for (var i=0;i<__invalidArray.length; i++)
			{
				if (tbx == __invalidArray[i]){
					return;		 
				}						
			}
			__invalidArray.push(tbx);		
		}
		else
		{
			//remove object if registered
			for (var i=0;i<__invalidArray.length; i++)
			{
				if (tbx == __invalidArray[i]){
					 __invalidArray.splice(i,1);		 
				}			
			}	
		}
		applyTbInvalidStyle(tbx,invalid);
	}

	//set styles for valid/invalid
	private function applyTbInvalidStyle(textbox:TextInput,invalid:Boolean):Void
	{
		if (invalid)
		{
			textbox.setStyle("borderColor", 0xff0000);
			textbox.setStyle("borderStyle", "solid");			
		}
		else
		{
			textbox.setStyle("borderStyle", "inset");
			textbox.setStyle("borderColor", 0xD5DDDD);
		}
	}
	
	private function setMessage():Void
	{
		__tbMsgInvalid.text = "";
		for (var i=0;i<__invalidArray.length; i++)
		{
			//add message to output, but only once
			var thisTbx = __invalidArray[i];
			var validationType = __fields[thisTbx];
			var thisMsg = __validations[validationType].description;
			if (__tbMsgInvalid.text.indexOf(thisMsg) == -1)
			{ 
				__tbMsgInvalid.text += thisMsg + newline;
			}
		}
	}
	
	public function validateAll():Boolean
	{
		for (var tbx in __fields)
		{
			validate(eval(tbx),__fields[tbx]);
		}
		return __invalidArray.length == 0;
	}

	//method to find out if a field is regitered invalid 
	public function fieldIsRegisteredInvalid(tbx):Boolean
	{
		for (var i=0;i<__invalidArray.length; i++)
		{
			if (tbx == __invalidArray[i]){
				return true;		 
			}						
		}
		return false;	
	}

	
	//properties
	public function set validationsXMLsrc(src:String):Void
	{
		__validationsXMLsrc =  src;
		this.loadValidationsXML(__validationsXMLsrc);
	}
	
	public function get validationsXMLsrc():String 
	{
	  return __validationsXMLsrc;
	}
	
	public function get validationsXML():XML 
	{
	  return __validationsXML;
	}
	
	//TextField|TextArea|Label|TextInput to display comment
	public function set msgTextBox(pNF:Object):Void
	{
		__tbMsgInvalid =  pNF;
	}
	
	public function get msgTextBox():Object 
	{
	  return __tbMsgInvalid;
	}
}		

If you have any comments or suggestions please let me know at info@bgxcomponents.com.