Adobe Flex 3 Help

Using validators

Triggering validation by using events

You can trigger validators automatically by associating them with an event. In the following example, the user enters a ZIP code in a TextInput control, and then triggers validation by clicking the Button control:

<?xml version="1.0"?>
<!-- validators\ZCValidatorTriggerEvent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:ZipCodeValidator id="zipV" 
        source="{myZip}" 
        property="text" 
        trigger="{mySubmit}" 
        triggerEvent="click"/>

    <mx:TextInput id="myZip"/> 
    <mx:Button id="mySubmit" label="Submit"/> 
</mx:Application>

The executing SWF file for the previous example is shown below:

This example uses the trigger and triggerEvent properties of the ZipCodeValidator class to associate an event with the validator. These properties have the following values:

trigger Specifies the component generating the event that triggers the validator. If omitted, by default Flex uses the value of the source property.

triggerEvent Specifies the event that triggers the validation. If omitted, Flex uses the valueCommit event. Flex dispatches the valueCommit event whenever the value of a control changes. Usually this is when the user removes focus from the component, or when a property value is changed programmatically. If you want a validator to ignore all events, set triggerEvent to an empty string ("").

For information on specific validator classes, see Using standard validators.

Triggering validation by using the default event

You can rewrite the example from the previous section to use default values for the trigger and triggerEvent properties, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ZCValidatorDefEvent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:ZipCodeValidator id="zipV" 
        source="{myZip}" 
        property="text"/>

    <mx:TextInput id="myZip"/> 
    <mx:Button id="mySubmit" label="Submit"/> 
</mx:Application>

The executing SWF file for the previous example is shown below:

By omitting the trigger and triggerEvent properties, Flex triggers the validator when the TextInput control dispatches the valueCommit event. Flex controls dispatch the valueCommit event when its values changes by user interaction or programmatically.

Triggering validation for data bindings

Data binding provides a syntax for automatically copying the value of a property of one object to a property of another object at run time. With data binding, Flex copies the source value to the destination, typically in response to a modification to the source. The source and destination of data bindings are typically Flex components or data models.

In the next example, you bind data entered in a TextInput control to a data model so that the data in the TextInput control is automatically copied to the data model:

<?xml version="1.0"?>
<!-- validators\ValWithDataBinding.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- Define a data model for storing the phone number. -->
    <mx:Model id="userInfo">
        <phoneInfo>
            <phoneNum>{phoneInput.text}</phoneNum>
        </phoneInfo>
    </mx:Model>

    <!-- Define the TextInput control for entering the phone number. -->
    <mx:TextInput id="phoneInput"/>
    <mx:TextInput id="zipCodeInput"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

You can use a validator along with a data binding to validate either the source or destination of the data binding, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ValTriggerWithDataBinding.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- Define a data model for storing the phone number. -->
    <mx:Model id="userInfo">
        <phoneInfo>
            <phoneNum>{phoneInput.text}</phoneNum>
        </phoneInfo>
    </mx:Model>

    <!-- Define the PhoneNumberValidator. -->
    <mx:PhoneNumberValidator id="pnV" 
        source="{phoneInput}" 
        property="text"/>

    <!-- Define the TextInput control for entering the phone number. -->
    <mx:TextInput id="phoneInput"/>
    <mx:TextInput id="zipCodeInput"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

This example uses a PhoneNumberValidator to validate the data entered in the TextInput control. In this example, the following occurs:

  • You assign the validator to the source of the data binding.
  • You use the default event, valueCommit, on the TextInput control to trigger the validator. This means the validator executes when the user removes focus from the TextInput control by selecting the TextInput control for the ZIP code.
  • Flex updates the destination of the data binding on every change to the source. This means that the userInfo.phoneNum field updates on every change to the TextInput control, while the validator executes only when the user removes focus from the TextInput control to trigger the valueCommit event. You can use the validator's triggerEvent property to specify a different event to trigger the validation.

In a model-view-controller (MVC) design pattern, you isolate the model from the view and controller portions of the application. In the previous example, the data model represents the model, and the TextInput control and validator represents the view.

The TextInput control is not aware that its data is bound to the data model, or that there is any binding on it at all. Since the validator is also assigned to the TextInput control, you have kept the model and view portions of your application separate and can modify one without affecting the other.

However, there is nothing in Flex to prohibit you from assigning a validator to the data model, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ValTriggerWithDataBindingOnModel.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- Define a data model for storing the phone number. -->
    <mx:Model id="userInfo">
        <phoneInfo>
            <phoneNum>{phoneInput.text}</phoneNum>
        </phoneInfo>
    </mx:Model>

    <!-- Define the PhoneNumberValidator. -->
    <mx:PhoneNumberValidator id="pnV" 
        source="{userInfo}" 
        property="phoneNum" 
        trigger="{phoneInput}" 
        listener="{phoneInput}"/>

    <!-- Define the TextInput control for entering the phone number. -->
    <mx:TextInput id="phoneInput"/>
    <mx:TextInput id="zipCodeInput"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you trigger the data validator by using the valueCommit event of the TextInput control, but assign the validator to a field of the data model, rather than to a property of the TextInput control.

This example also uses the listener property of the validator. This property configures the validator to display validation error information on the specified object, rather than on the source of the validation. In this example, the source of the validation is a model, so you display the visual information on the TextInput control that provided the data to the model. For more information, see Specifying a listener for validation.

If the model has a nesting structure of elements, you use dot-delimited Strings with the source property to specify the model element to validate, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ValTriggerWithDataBindingComplexModel.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- Define a data model for storing the phone number. -->
    <mx:Model id="userInfo">
        <user>
            <phoneInfo>
                <homePhoneNum>{homePhoneInput.text}</homePhoneNum>
                <cellPhoneNum>{cellPhoneInput.text}</cellPhoneNum>
            </phoneInfo>
        </user>
    </mx:Model>

    <!-- Define the PhoneNumberValidator. -->
    <mx:PhoneNumberValidator id="hPNV" 
        source="{userInfo.phoneInfo}" 
        property="homePhoneNum" 
        trigger="{homePhoneInput}" 
        listener="{homePhoneInput}"/>

    <!-- Define the PhoneNumberValidator. -->
    <mx:PhoneNumberValidator id="cPNV" 
        source="{userInfo.phoneInfo}" 
        property="cellPhoneNum" 
        trigger="{cellPhoneInput}" 
        listener="{cellPhoneInput}"/>

    <!-- Define the TextInput controls for entering the phone number. -->
    <mx:Label text="Home Phone:"/>
    <mx:TextInput id="homePhoneInput"/>

    <mx:Label text="Cell Phone:"/>
    <mx:TextInput id="cellPhoneInput"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

Triggering validation programmatically

The Validator class, and all subclasses of Validator, include a validate() method that you can call to invoke a validator directly, rather than triggering the validator automatically by using an event.

The validate() method has the following signature:

validate(value:Object = null, supressEvents:Boolean = false):ValidationResultEvent

The arguments have the following values:

value 

If value is null, use the source and property properties to specify the data to validate. If value is non-null, it specifies a field of an object relative to the this keyword, which means an object in the scope of the document.



You should also set the Validator.listener property when you specify the value argument. When a validation occurs, Flex applies visual changes to the object specified by the listener property. By default, Flex sets the listener property to the value of the source property. However, because you do not specify the source property when you pass the value argument, you should set it explicitly. For more information, see Specifying a listener for validation.

supressEvents 

If false, dispatch either the valid or invalid event on completion. If true, do not dispatch events.



This method returns an event object containing the results of the validation that is an instance of the ValidationResultEvent class. For more information on using the return result, see Handling the return value of the validate() method.

In the following example, you create and invoke a validator programmatically in when a user clicks a Button control:

<?xml version="1.0"?>
<!-- validators\ValTriggerProg.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[

            // Import ZipCodeValidator.
            import mx.validators.ZipCodeValidator;

            private var v:ZipCodeValidator = new ZipCodeValidator();

            private function performValidation():void {
                v.domain = "US or Canada";
                // Set the listener property to the component 
                // used to display validation errors. 
                v.listener=myZip;
                v.validate(myZip.text);
            }
        ]]>
    </mx:Script>

    <mx:TextInput id="myZip"/>
    <mx:Button label="Submit" click="performValidation();"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

Notice that you are still using an event to trigger the performValidation() function that creates and invokes the validator, but the event itself does not automatically invoke the validator.

Any errors in the validator are shown on the associated component, just as if you had triggered the validation directly by using an event.

Handling the return value of the validate() method

You may want to inspect the return value from the validate() method to perform some action when the validation succeeds or fails. The validate() method returns an event object with a type defined by the ValidationResultEvent class.

The ValidationResultEvent class defines several properties, including the type property. The type property of the event object contains either ValidationResultEvent.VALID or ValidationResultEvent.INVALID, based on the validation results. You can use this property as part of your validation logic, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ValTriggerProgProcessReturnResult.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[

            // Import the ValidationResultEvent class.
            import mx.events.ValidationResultEvent;
            import mx.validators.ZipCodeValidator;

            public var v:ZipCodeValidator = new ZipCodeValidator();

            // Define variable for storing the validation event object.
            public var vResult:ValidationResultEvent;

            public function performValidation():void {
                v.domain = "US or Canada";
                v.listener=myZip;
                vResult = v.validate(myZip.text);
        
                if (vResult.type==ValidationResultEvent.VALID) {
                    // Validation succeeded.
                    myTA.text='OK';
                }
                else {
                    // Validation failed.
                    myTA.text='Fail';
                }
            }
        ]]>
    </mx:Script>
    
    <mx:TextInput id="myZip"/>
    <mx:Button label="Submit" click="performValidation();"/>
    
    <mx:TextArea id="myTA"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

The ValidationResultEvent class has additional properties that you can use when processing validation events. For more information, see Working with validation events.

Triggering the DateValidator and CreditCardValidator

The DateValidator and CreditCardValidator can validate multiple fields by using a single validator. A CreditCardValidator examines one field that contains the credit card number and a second field that contains the credit card type. The DateValidator can examine a single field that contains a date, or multiple fields that together make up a date.

When you validate an object that contains multiple properties that are set independently, you often cannot use events to automatically trigger the validator because no single field contains all of the information required to perform the validation.

One way to validate a complex object is to call the validate() method of the validator based on some type of user interaction. For example, you might want to validate the multiple fields that make up a date in response to the click event of a Button control, as the following example shows:

<?xml version="1.0"?>
<!-- validators\DateAndCC.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <!-- Define the data model. -->
    <mx:Model id="date">
        <dateInfo>
            <month>{monthInput.text}</month>
            <day>{dayInput.text}</day>
            <year>{yearInput.text}</year>
        </dateInfo>
    </mx:Model>

    <!-- Define the validators. -->
    <mx:DateValidator id="dayV" 
        triggerEvent="" 
        daySource="{dayInput}" 
        dayProperty="text" 
        monthSource="{monthInput}" 
        monthProperty="text" 
        yearSource="{yearInput}" 
        yearProperty="text"/>

    <!-- Define the form to populate the model. -->
    <mx:Form>
        <mx:TextInput id="monthInput"/>
        <mx:TextInput id="dayInput"/>
        <mx:TextInput id="yearInput"/>
    </mx:Form>

    <!-- Define the button to trigger validation. -->
    <mx:Button label="Submit"
        click="dayV.validate();"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

The validator in this example examines all three input fields. If any field is invalid, validation fails. The validator highlights only the invalid fields that failed. For more information on how validators signal validation errors, see Working with validation errors. For more information on the DateValidator and CreditCardValidator, see Using standard validators.

Invoking multiple validators in a function

You can invoke multiple validators programmatically from a single function. In this example, you use the ZipCodeValidator and PhoneNumberValidator validators to validate the ZIP code and phone number input to a data model.

<?xml version="1.0"?>
<!-- validators\ValidatorCustomFuncStaticVals.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
    
            // Import event class.
            import mx.events.ValidationResultEvent;
    
            // Define variable for storing the validation event object.
            private var vResult:ValidationResultEvent;
    
            private function validateZipPhone():void {       
                // Validate the ZIP code. 
                vResult = zipV.validate();                
                // If the ZIP code is invalid, 
                // do not move on to the next field.
                if (vResult.type==ValidationResultEvent.INVALID) 
                    return;
            
                // Validate the phone number. 
                vResult = pnV.validate();
                // If the phone number is invalid, 
                // do not move on to the validation.
                if (vResult.type==ValidationResultEvent.INVALID) 
                    return;
            }
        ]]>
    </mx:Script>

    <mx:Model id="person">
        <userInfo>
            <zipCode>{zipCodeInput.text}</zipCode>
            <phoneNumber>{phoneNumberInput.text}</phoneNumber>
        </userInfo>
    </mx:Model>

    <!-- Define the validators. -->
    <mx:ZipCodeValidator id="zipV" 
        source="{zipCodeInput}" 
        property="text"/>
    <mx:PhoneNumberValidator id="pnV" 
        source ="{phoneNumberInput}" 
        property="text"/>
    
    <mx:Form>
        <!-- Collect input data -->
        <mx:TextInput id="zipCodeInput"/>
        <mx:TextInput id="phoneNumberInput"/>
    </mx:Form>
    
    <mx:Button label="Validate" 
        click="validateZipPhone();"/> 
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you use the predefined ZipCodeValidator and PhoneNumberValidator to validate user information as the user enters it. Then, when the user clicks the Submit button to submit the form, you validate that the ZIP code is actually within the specified area code of the phone number.

You can also use the static Validator.validateAll() method to invoke all of the validators in an Array. This method returns an Array containing one ValidationResultEvent object for each validator that failed, and an empty Array if all validators succeed. The following example uses this method to invoke two validators in response to the click event for the Button control:

<?xml version="1.0"?>
<!-- validators\ValidatorMultipleValids.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="initValidatorArray();"> 

    <mx:Script>
        <![CDATA[
            import mx.validators.Validator;
        
            // Define the validator Array.
            private var myValidators:Array;

            private function initValidatorArray():void {
                myValidators=[zipV, pnV];
            }
        ]]>
    </mx:Script>

    <mx:Model id="person">
        <userInfo>
            <zipCode>{zipCodeInput.text}</zipCode>
            <phoneNumber>{phoneNumberInput.text}</phoneNumber>
        </userInfo>
    </mx:Model>

    <!-- Define the validators. -->
    <mx:ZipCodeValidator id="zipV" 
        source="{zipCodeInput}" 
        property="text"/>
    <mx:PhoneNumberValidator id="pnV" 
        source ="{phoneNumberInput}" 
        property="text"/>

    <mx:Form>
        <!-- Collect input data -->
        <mx:TextInput id="zipCodeInput"/>
        <mx:TextInput id="phoneNumberInput"/>
    </mx:Form>

    <mx:Button label="Validate" 
        click="Validator.validateAll(myValidators);"/> 
</mx:Application>

The executing SWF file for the previous example is shown below:

Creating a reusable validator

You can define a reusable validator so that you can use it to validate multiple fields. To make it reusable, you programmatically set the source and property properties to specify the field to validate, or pass that information to the validate() method, as the following example shows:

<?xml version="1.0"?>
<!-- validators\ReusableVals.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:Script>
        <![CDATA[

            import flash.events.Event;
    
            private function performValidation(eventObj:Event):void {
                zipV.listener=eventObj.currentTarget;
                zipV.validate(eventObj.currentTarget.text);
            }
        ]]>
    </mx:Script>

    <mx:ZipCodeValidator id="zipV" 
        triggerEvent=""/>

    <mx:TextInput id="shippingZip" 
        focusOut="performValidation(event);"/>
    <mx:TextInput id="billingZip" 
        focusOut="performValidation(event);"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you have two address areas for a customer: one for a billing address and one for a shipping address. Both addresses have a ZIP code field, so you can reuse a single ZipCodeValidator for both fields. The event listener for the focusOut event passes the field to validate to the validate() method.

Alternatively, you can write the performValidation() function as the following example shows:

<?xml version="1.0"?>
<!-- validators\ReusableValsSpecifySource.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:Script>
        <![CDATA[

            import flash.events.Event;
    
            private function performValidation(eventObj:Event):void {
                zipV.source = eventObj.currentTarget;
                zipV.property = "text";
                zipV.validate();
            }
        ]]>
    </mx:Script>

    <mx:ZipCodeValidator id="zipV" 
        triggerEvent=""/>

    <mx:TextInput id="shippingZip" 
        focusOut="performValidation(event);"/>
    <mx:TextInput id="billingZip" 
        focusOut="performValidation(event);"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

Conditionalizing validator execution

By invoking a validator programmatically, you can use conditional logic in your application to determine which of several validators to invoke, set validator properties, or perform other preprocessing or postprocessing as part of the validation.

In the next example, you use a Button control to invoke a validator, but the application first determines which validator to execute, based on user input:

<?xml version="1.0"?>
<!-- validators\ConditionalVal.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:Script>
        <![CDATA[

            import mx.events.ValidationResultEvent;
    
            private var vEvent:ValidationResultEvent;
    
            private function validateData():void {
                if (country.selectedValue == "Canada") {
                    vEvent = zipCN.validate(zipInput.text);
                }
                else            {
                    vEvent = zipUS.validate(zipInput.text);
                }
            }
        ]]>
    </mx:Script>

    <mx:ZipCodeValidator id="zipUS" 
        domain="US Only" 
        listener="{zipInput}"/>
    <mx:ZipCodeValidator id="zipCN" 
        domain="US or Canada" 
        listener="{zipInput}"/>

    <mx:RadioButtonGroup id="country"/>
    <mx:RadioButton groupName="country" label="US"/>
    <mx:RadioButton groupName="country" label="Canada"/>

    <mx:TextInput id="zipInput"/>

    <mx:Button label="Submit" click="validateData();"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you use a ZipCodeValidator to validate a ZIP code entered into a TextInput control. However, the validateData() function must first determine whether the ZIP code is for the U.S. or for Canada before performing the validation. In this example, the application uses the RadioButton controls to let the user specify the country as part of entering the ZIP code.

Validating required fields

The Validator class, the base class for all Flex validators, contains a required property that when set to true causes validation to fail when a field is empty. You use this property to configure the validator to fail when a user does not enter data in a required input field.

You typically call the validate() method to invoke a validator on a required field. This is often necessary because you cannot guarantee that an event occurs to trigger the validation-- an empty input field often means that the user never gave the input control focus.

The following example performs a validation on a required input field:

<?xml version="1.0"?>
<!-- validators\RequiredVal.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:StringValidator id="reqV" 
        source="{inputA}" 
        property="text" 
        required="true"/>

    <mx:TextInput id="inputA"/> 

    <mx:Button label="Submit" 
        click="reqV.validate();"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, the StringValidator executes when the following occurs:

  • The TextInput control dispatches the valueCommit event. However, to dispatch that event, the user must give the TextInput control focus, and then remove focus. If the user never gives the TextInput control focus, the validator does not trigger, and Flex does not recognize that the control is empty. Therefore, you must call the validate() method to ensure that the validator checks for missing data.
  • The user clicks the Button control. The validator issues a validation error when the user does not enter any data into the TextInput control. It also issues a validation error if the user enters an invalid String value.

Enabling and disabling a validator

The Validator.enabled property lets you enable and disable a validator. When the value of the enabled property is true, the validator is enabled; when the value is false, the validator is disabled. When a validator is disabled, it dispatches no events, and the validate() method returns null.

For example, you can set the enabled property by using data binding, as the following code shows:

<?xml version="1.0"?>
<!-- validators\EnableVal.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:ZipCodeValidator id="zcVal" 
        source="{inputA}" 
        property="text" 
        required="true" 
        enabled="{enableV.selected}"/>

    <mx:TextInput id="inputA"/> 
    <mx:TextInput/> 
    <mx:CheckBox id="enableV" 
        label="Validate input?"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you enable the validator only when the user selects the CheckBox control.

Using data binding to configure validators

You configure validators to match your application requirements. For example, the StringValidator lets you specify a minimum and maximum length of a valid string. For a String to be considered valid, it must be at least the minimum number of characters long, and less than or equal to the maximum number of characters.

Often, you set validator properties statically, which means that they do not change as your application executes. For example, the following StringValidator defines that the input string must be at least one character long and no longer than 10 characters:

<mx:StringValidator required="true" minlength="1" maxLength="10"/>

User input might also define the properties of the validator. In the following example, you let the user set the minimum and maximum values of a NumberValidator:

<?xml version="1.0"?>
<!-- validators\ConfigWithBinding.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 

    <mx:NumberValidator 
        source="{inputA}" 
        property="text"  
        minValue="{Number(inputMin.text)}" 
        maxValue="{Number(inputMax.text)}"/>

    <mx:TextInput id="inputA"/>
    <mx:TextInput id="inputMin" text="1"/>
    <mx:TextInput id="inputMax" text="10"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

In this example, you use data binding to configure the properties of the validators.