A validator can validate more than one field at a time. For example, you could create a custom validator called NameValidator to validate three input controls that represent a person's first, middle, and last names.
To create a validator that examines multiple fields, you can either define properties on the validator that let you specify the multiple input fields, as does the Flex DateValidator class, or you can require that the single item passed to the validator includes all of the fields to be validated.
In the following example, you use a NameValidator that validates an item that contains three fields named first, middle, and last:
<?xml version="1.0" ?>
<!-- validators/MainNameValidator.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:MyComp="myValidators.*">
<mx:Model id="person">
<name>
<custName>
<first>{firstInput.text}</first>
<middle>{middleInput.text}</middle>
<last>{lastInput.text}</last>
</custName>
</name>
</mx:Model>
<mx:TextInput id="firstInput"/>
<mx:TextInput id="middleInput"/>
<mx:TextInput id="lastInput"/>
<MyComp:NameValidator id="nameVal"
source="{person}" property="custName"
listener="{firstInput}"/>
<mx:Button label="Validate" click="nameVal.validate();"/>
</mx:Application>
The executing SWF file for the previous example is shown below:
This validator examines three input fields. You specify firstInput as the validation listener. Therefore, when a validation error occurs, Flex shows a validation error message on the first TextInput control.
You can implement the NameValidator class, as the following example shows:
package myValidators
{
import mx.validators.Validator;
import mx.validators.ValidationResult;
public class NameValidator extends Validator {
// Define Array for the return value of doValidation().
private var results:Array;
public function NameValidator () {
super();
}
override protected function doValidation(value:Object):Array {
var fName:String = value.first;
var mName:String = value.middle;
var lName:String = value.last;
// Clear results Array.
results = [];
// Call base class doValidation().
results = super.doValidation(value);
// Return if there are errors.
if (results.length > 0)
return results;
// Check first name field.
if (fName == "" || fName == null) {
results.push(new ValidationResult(true,
"first", "noFirstName", "No First Name."));
return results;
}
// Check middle name field.
if (mName == "" || mName == null) {
results.push(new ValidationResult(true,
"middle", "noMiddleName", "No Middle Name."));
return results;
}
// Check last name field.
if (lName == "" || lName == null) {
results.push(new ValidationResult(true,
"last", "noLastName", "No Last Name."));
return results;
}
return results;
}
}
}
In this example, because you are using a single validator to validate three subfields of the Object passed to the validator, you include the optional second argument to the constructor for the ValidationResult class to specify the subfield that caused the validation error. This inclusion permits Flex to identify the input component that caused the error, and to highlight that component in the application.
The doValidation() method returns a validation error as soon as it detects the first validation error. You can modify doValidation() so that it examines all of the input fields before returning an error message, as the following example shows. This custom validator is named NameValidatorAllFields.as:
package myValidators
{
import mx.validators.Validator;
import mx.validators.ValidationResult;
public class NameValidatorAllFields extends Validator {
// Define Array for the return value of doValidation().
private var results:Array;
public function NameValidatorAllFields() {
super();
}
override protected function doValidation(value:Object):Array {
var fName:String = value.first;
var mName:String = value.middle;
var lName:String = value.last;
// Clear results Array.
results = [];
// Call base class doValidation().
results = super.doValidation(value);
// Return if there are errors.
if (results.length > 0)
return results;
// Check first name field.
if (fName == "" || fName == null) {
results.push(new ValidationResult(true,
"first", "noFirstName", "No First Name."));
}
// Check middle name field.
if (mName == "" || mName == null) {
results.push(new ValidationResult(true,
"middle", "noMiddleName", "No Middle Name."));
}
// Check last name field.
if (lName == "" || lName == null) {
results.push(new ValidationResult(true,
"last", "noLastName", "No Last Name."));
}
return results;
}
}
}
Notice that you remove the return statement from the body of the if statements so that the method contains only a single return statement. This modification allows you to detect three different validation errors at once.