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
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
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;
}
}