//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.validators { import mx.managers.ISystemManager; import mx.managers.SystemManager; [ResourceBundle("SharedResources")] [ResourceBundle("validators")] [Alternative(replacement="spark.validators.CurrencyValidator", since="4.5")] /** * The CurrencyValidator class ensures that a String * represents a valid currency expression. * It can make sure the input falls within a given range * (specified by minValue and maxValue), * is non-negative (specified by allowNegative), * and does not exceed the specified precision. The * CurrencyValidator class correctly validates formatted and unformatted * currency expressions, e.g., "$12,345.00" and "12345". * You can customize the currencySymbol, alignSymbol, * thousandsSeparator, and decimalSeparator * properties for internationalization. * * @mxml * *

The <mx:CurrencyValidator> tag * inherits all of the tag properties of its superclass, * and adds the following tag properties:

* *
 *  <mx:CurrencyValidator
 *    alignSymbol="left|right|any"
 *    allowNegative="true|false"
 *    currencySymbol="$"
 *    currencySymbolError="The currency symbol occurs in an invalid location."
 *    decimalPointCountError="The decimal separator can occur only once."
 *    decimalSeparator="."
 *    exceedsMaxError="The amount entered is too large."
 *    invalidCharError="The input contains invalid characters."
 *    invalidFormatCharsError="One of the formatting parameters is invalid."
 *    lowerThanMinError="The amount entered is too small."
 *    maxValue="NaN"
 *    minValue="NaN"
 *    negativeError="The amount may not be negative."
 *    precision="2"
 *    precisionError="The amount entered has too many digits beyond the decimal point."
 *    separationError="The thousands separator must be followed by three digits."
 *    thousandsSeparator=","
 *  />
 *  
* * @see mx.validators.CurrencyValidatorAlignSymbol * * @includeExample examples/CurrencyValidatorExample.mxml * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class CurrencyValidator extends Validator { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * @private * Formatting characters for negative values. */ private static const NEGATIVE_FORMATTING_CHARS:String = "-()"; //-------------------------------------------------------------------------- // // Class methods // //-------------------------------------------------------------------------- /** * Convenience method for calling a validator. * Each of the standard Flex validators has a similar convenience method. * * @param validator The CurrencyValidator instance. * * @param value The object to validate. * * @param baseField Text representation of the subfield * specified in the value parameter. * For example, if the value parameter specifies value.currency, * the baseField value is "currency". * * @return An Array of ValidationResult objects, with one ValidationResult * object for each field examined by the validator. * * @see mx.validators.ValidationResult * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public static function validateCurrency(validator:CurrencyValidator, value:Object, baseField:String):Array { var results:Array = []; // Resource-backed properties of the validator. var alignSymbol:String = validator.alignSymbol; var allowNegative:Boolean = validator.allowNegative; var currencySymbol:String = validator.currencySymbol; var decimalSeparator:String = validator.decimalSeparator; var maxValue:Number = Number(validator.maxValue); var minValue:Number = Number(validator.minValue); var precision:int = int(validator.precision); var thousandsSeparator:String = validator.thousandsSeparator; var input:String = String(value); var len:int = input.length; var isNegative:Boolean = false; var i:int; var c:String; // Make sure the formatting character parameters are unique, // are not digits or negative formatting characters, // and that the separators are one character. var invalidFormChars:String = DECIMAL_DIGITS + NEGATIVE_FORMATTING_CHARS; if (currencySymbol == thousandsSeparator || currencySymbol == decimalSeparator || decimalSeparator == thousandsSeparator || invalidFormChars.indexOf(currencySymbol) != -1 || invalidFormChars.indexOf(decimalSeparator) != -1 || invalidFormChars.indexOf(thousandsSeparator) != -1 || decimalSeparator.length != 1 || thousandsSeparator.length != 1) { results.push(new ValidationResult( true, baseField, "invalidFormatChar", validator.invalidFormatCharsError)); return results; } // Check for invalid characters in input. var validChars:String = DECIMAL_DIGITS + NEGATIVE_FORMATTING_CHARS + currencySymbol + decimalSeparator + thousandsSeparator; for (i = 0; i < len; i++) { c = input.charAt(i); if (validChars.indexOf(c) == -1) { results.push(new ValidationResult( true, baseField, "invalidChar", validator.invalidCharError)); return results; } } // Check if the input is negative. if (input.charAt(0) == "-") { // Check if negative input is allowed. if (!allowNegative) { results.push(new ValidationResult( true, baseField, "negative", validator.negativeError)); return results; } // Strip off the negative formatting and update some variables. input = input.substring(1); len--; isNegative = true; } else if (input.charAt(0) == "(") { // Make sure the last character is a closed parenthesis. if (input.charAt(len - 1) != ")") { results.push(new ValidationResult( true, baseField, "invalidChar", validator.invalidCharError)); return results; } // Check if negative input is allowed. if (!allowNegative) { results.push(new ValidationResult( true, baseField, "negative", validator.negativeError)); return results; } // Strip off the negative formatting and update some variables. input = input.substring(1,len-2); len -= 2; isNegative = true; } // Find the currency symbol if it exists, // then make sure that it's in the right place // and that there is only one. var currencySymbolLength:uint = currencySymbol.length; // allows for symbols that use multiple chars, like the Brazilian "R$" if ((input.substr(0, currencySymbolLength) == currencySymbol && alignSymbol == CurrencyValidatorAlignSymbol.RIGHT) || (input.substr(len - currencySymbolLength, currencySymbolLength) == currencySymbol && alignSymbol == CurrencyValidatorAlignSymbol.LEFT) || (len > (2 * currencySymbolLength) && input.substring(currencySymbolLength, len - currencySymbolLength).indexOf(currencySymbol) != -1) || (input.indexOf(currencySymbol) != input.lastIndexOf(currencySymbol))) { results.push(new ValidationResult( true, baseField, "currencySymbol", validator.currencySymbolError)); return results; } // Now that we know it's in the right place, // strip off the currency symbol if it exists. var currencySymbolIndex:int = input.indexOf(currencySymbol); if (currencySymbolIndex != -1) { if (currencySymbolIndex) // if it's at the end input = input.substring(0, len - currencySymbolLength); else // it's at the beginning input = input.substring(currencySymbolLength); len -= currencySymbolLength; } // Make sure there is only one decimal point. if (input.indexOf(decimalSeparator) != input.lastIndexOf(decimalSeparator)) { results.push(new ValidationResult( true, baseField, "decimalPointCount", validator.decimalPointCountError)); return results; } // Make sure that every character after the decimal point // is a digit and that the precision is not exceeded. var decimalSeparatorIndex:int = input.indexOf(decimalSeparator); var numDigitsAfterDecimal:int = 0; // If there is no decimal separator, act like there is one at the end. if (decimalSeparatorIndex == -1) decimalSeparatorIndex = len; for (i = decimalSeparatorIndex + 1; i < len; i++) { if (DECIMAL_DIGITS.indexOf(input.charAt(i)) == -1) { results.push(new ValidationResult( true, baseField, "invalidChar", validator.invalidCharError)); return results; } ++numDigitsAfterDecimal; // Make sure precision is not exceeded. if (precision != -1 && numDigitsAfterDecimal > precision) { results.push(new ValidationResult( true, baseField, "precision", validator.precisionError)); return results; } } // Make sure the input begins with a digit or a decimal point. if (DECIMAL_DIGITS.indexOf(input.charAt(0)) == -1 && input.charAt(0) != decimalSeparator) { results.push(new ValidationResult( true, baseField, "invalidChar", validator.invalidCharError)); return results; } // Make sure that every character before the decimal point // is a digit or is a thousands separator. // If it's a thousands separator, make sure it's followed // by three consecutive digits, and then make sure the next character // is valid (i.e., either thousands separator, decimal separator, // or nothing). var validGroupEnder:String = thousandsSeparator + decimalSeparator; for (i = 1; i < decimalSeparatorIndex; i++) { c = input.charAt(i); if (c == thousandsSeparator) { if (input.substring(i + 1, i + 4).length < 3 || DECIMAL_DIGITS.indexOf(input.charAt(i + 1)) == -1 || DECIMAL_DIGITS.indexOf(input.charAt(i + 2)) == -1 || DECIMAL_DIGITS.indexOf(input.charAt(i + 3)) == -1 || validGroupEnder.indexOf(input.charAt(i + 4)) == -1) { results.push(new ValidationResult( true, baseField, "separation", validator.separationError)); return results; } } else if (DECIMAL_DIGITS.indexOf(c) == -1) { results.push(new ValidationResult( true, baseField, "invalidChar", validator.invalidCharError)); return results; } } // Make sure the input is within the specified range. if (!isNaN(minValue) || !isNaN(maxValue)) { // First strip off the thousands separators. for (i = 0; i < decimalSeparatorIndex; i++) { if (input.charAt(i) == thousandsSeparator) { var left:String = input.substring(0, i); var right:String = input.substring(i + 1); input = left + right; } } // Translate the value back into standard english // If the decimalSeperator is not '.' we need to change it to '.' // so that the number casting will work properly if (validator.decimalSeparator != '.') { var dIndex:int = input.indexOf( validator.decimalSeparator ); if (dIndex != -1) { var dLeft:String = input.substring(0, dIndex); var dRight:String = input.substring(dIndex + 1); input = dLeft + '.' + dRight; } } // Check bounds var x:Number = Number(input); if (isNegative) x = -x; if (!isNaN(minValue) && x < minValue) { results.push(new ValidationResult( true, baseField, "lowerThanMin", validator.lowerThanMinError)); return results; } if (!isNaN(maxValue) && x > maxValue) { results.push(new ValidationResult( true, baseField, "exceedsMax", validator.exceedsMaxError)); return results; } } return results; } //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function CurrencyValidator() { super(); } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // alignSymbol //---------------------------------- /** * @private * Storage for the alignSymbol property. */ private var _alignSymbol:String; /** * @private */ private var alignSymbolOverride:String; [Inspectable(category="General", defaultValue="null")] /** * Specifies the alignment of the currencySymbol * relative to the rest of the expression. * Acceptable values in ActionScript are CurrencyValidatorAlignSymbol.LEFT, * CurrencyValidatorAlignSymbol.RIGHT, and * CurrencyValidatorAlignSymbol.ANY. * Acceptable values in MXML are "left", * "right", and * "any". * * @default CurrencyValidatorAlignSymbol.LEFT * * @see mx.validators.CurrencyValidatorAlignSymbol * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get alignSymbol():String { return _alignSymbol; } /** * @private */ public function set alignSymbol(value:String):void { alignSymbolOverride = value; _alignSymbol = value != null ? value : resourceManager.getString( "SharedResources", "alignSymbol"); } //---------------------------------- // allowNegative //---------------------------------- /** * @private * Storage for the allowNegative property. */ private var _allowNegative:Object; /** * @private */ private var allowNegativeOverride:Object; [Inspectable(category="General", defaultValue="null")] /** * Specifies whether negative numbers are permitted. * Can be true or false. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get allowNegative():Object { return _allowNegative; } /** * @private */ public function set allowNegative(value:Object):void { allowNegativeOverride = value; _allowNegative = value != null ? Boolean(value) : resourceManager.getBoolean( "validators", "allowNegative"); } //---------------------------------- // currencySymbol //---------------------------------- /** * @private * Storage for the currencySymbol property. */ private var _currencySymbol:String; /** * @private */ private var currencySymbolOverride:String; [Inspectable(category="General", defaultValue="null")] /** * The character String used to specify the currency symbol, * such as "$", "R$", or "£". * Cannot be a digit and must be distinct from the * thousandsSeparator and the decimalSeparator. * * @default "$" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get currencySymbol():String { return _currencySymbol; } /** * @private */ public function set currencySymbol(value:String):void { currencySymbolOverride = value; _currencySymbol = value != null ? value : resourceManager.getString( "SharedResources", "currencySymbol"); } //---------------------------------- // decimalSeparator //---------------------------------- /** * @private * Storage for the decimalSeparator property. */ private var _decimalSeparator:String; /** * @private */ private var decimalSeparatorOverride:String; [Inspectable(category="General", defaultValue="null")] /** * The character used to separate the whole * from the fractional part of the number. * Cannot be a digit and must be distinct from the * currencySymbol and the thousandsSeparator. * * @default "." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get decimalSeparator():String { return _decimalSeparator; } /** * @private */ public function set decimalSeparator(value:String):void { decimalSeparatorOverride = value; _decimalSeparator = value != null ? value : resourceManager.getString( "validators", "decimalSeparator"); } //---------------------------------- // maxValue //---------------------------------- /** * @private * Storage for the maxValue property. */ private var _maxValue:Object; /** * @private */ private var maxValueOverride:Object; [Inspectable(category="General", defaultValue="null")] /** * Maximum value for a valid number. * A value of NaN means it is ignored. * * @default NaN * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get maxValue():Object { return _maxValue; } /** * @private */ public function set maxValue(value:Object):void { maxValueOverride = value; _maxValue = value != null ? Number(value) : resourceManager.getNumber( "validators", "maxValue"); } //---------------------------------- // minValue //---------------------------------- /** * @private * Storage for the minValue property. */ private var _minValue:Object; /** * @private */ private var minValueOverride:Object; [Inspectable(category="General", defaultValue="null")] /** * Minimum value for a valid number. * A value of NaN means it is ignored. * * @default NaN * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get minValue():Object { return _minValue; } /** * @private */ public function set minValue(value:Object):void { minValueOverride = value; _minValue = value != null ? Number(value) : resourceManager.getNumber( "validators", "minValue"); } //---------------------------------- // precision //---------------------------------- /** * @private * Storage for the precision property. */ private var _precision:Object; /** * @private */ private var precisionOverride:Object; [Inspectable(category="General", defaultValue="null")] /** * The maximum number of digits allowed to follow the decimal point. * Can be any non-negative integer. * Note: Setting to 0 * has the same effect as setting NumberValidator.domain * to int. * Setting it to -1, means it is ignored. * * @default 2 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get precision():Object { return _precision; } /** * @private */ public function set precision(value:Object):void { precisionOverride = value; _precision = value != null ? int(value) : resourceManager.getInt( "validators", "currencyValidatorPrecision"); } //---------------------------------- // thousandsSeparator //---------------------------------- /** * @private * Storage for the thousandsSeparator property. */ private var _thousandsSeparator:String; /** * @private */ private var thousandsSeparatorOverride:String; [Inspectable(category="General", defaultValue=",")] /** * The character used to separate thousands. * Cannot be a digit and must be distinct from the * currencySymbol and the decimalSeparator. * * @default "," * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get thousandsSeparator():String { return _thousandsSeparator; } /** * @private */ public function set thousandsSeparator(value:String):void { thousandsSeparatorOverride = value; _thousandsSeparator = value != null ? value : resourceManager.getString( "validators", "thousandsSeparator"); } //-------------------------------------------------------------------------- // // Properties: Errors // //-------------------------------------------------------------------------- //---------------------------------- // currencySymbolError //---------------------------------- /** * @private * Storage for the currencySymbolError property. */ private var _currencySymbolError:String; /** * @private */ private var currencySymbolErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the currency symbol, defined by currencySymbol, * is in the wrong location. * * @default "The currency symbol occurs in an invalid location." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get currencySymbolError():String { return _currencySymbolError; } /** * @private */ public function set currencySymbolError(value:String):void { currencySymbolErrorOverride = value; _currencySymbolError = value != null ? value : resourceManager.getString( "validators", "currencySymbolError"); } //---------------------------------- // decimalPointCountError //---------------------------------- /** * @private * Storage for the decimalPointCountError property. */ private var _decimalPointCountError:String; /** * @private */ private var decimalPointCountErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the decimal separator character occurs more than once. * * @default "The decimal separator can only occur once." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get decimalPointCountError():String { return _decimalPointCountError; } /** * @private */ public function set decimalPointCountError(value:String):void { decimalPointCountErrorOverride = value; _decimalPointCountError = value != null ? value : resourceManager.getString( "validators", "decimalPointCountError"); } //---------------------------------- // exceedsMaxError //---------------------------------- /** * @private * Storage for the exceedsMaxError property. */ private var _exceedsMaxError:String; /** * @private */ private var exceedsMaxErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the value is greater than maxValue. * * @default "The amount entered is too large." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get exceedsMaxError():String { return _exceedsMaxError; } /** * @private */ public function set exceedsMaxError(value:String):void { exceedsMaxErrorOverride = value; _exceedsMaxError = value != null ? value : resourceManager.getString( "validators", "exceedsMaxErrorCV"); } //---------------------------------- // invalidCharError //---------------------------------- /** * @private * Storage for the invalidCharError property. */ private var _invalidCharError:String; /** * @private */ private var invalidCharErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the currency contains invalid characters. * * @default "The input contains invalid characters." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get invalidCharError():String { return _invalidCharError; } /** * @private */ public function set invalidCharError(value:String):void { invalidCharErrorOverride = value; _invalidCharError = value != null ? value : resourceManager.getString( "validators", "invalidCharError"); } //---------------------------------- // invalidFormatCharsError //---------------------------------- /** * @private * Storage for the invalidFormatCharsError property. */ private var _invalidFormatCharsError:String; /** * @private */ private var invalidFormatCharsErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the value contains an invalid formatting character. * * @default "One of the formatting parameters is invalid." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get invalidFormatCharsError():String { return _invalidFormatCharsError; } /** * @private */ public function set invalidFormatCharsError(value:String):void { invalidFormatCharsErrorOverride = value; _invalidFormatCharsError = value != null ? value : resourceManager.getString( "validators", "invalidFormatCharsError"); } //---------------------------------- // lowerThanMinError //---------------------------------- /** * @private * Storage for the lowerThanMinError property. */ private var _lowerThanMinError:String; /** * @private */ private var lowerThanMinErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the value is less than minValue. * * @default "The amount entered is too small." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get lowerThanMinError():String { return _lowerThanMinError; } /** * @private */ public function set lowerThanMinError(value:String):void { lowerThanMinErrorOverride = value; _lowerThanMinError = value != null ? value : resourceManager.getString( "validators", "lowerThanMinError"); } //---------------------------------- // negativeError //---------------------------------- /** * @private * Storage for the negativeError property. */ private var _negativeError:String; /** * @private */ private var negativeErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the value is negative and * the allowNegative property is false. * * @default "The amount may not be negative." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get negativeError():String { return _negativeError; } /** * @private */ public function set negativeError(value:String):void { negativeErrorOverride = value; _negativeError = value != null ? value : resourceManager.getString( "validators", "negativeError"); } //---------------------------------- // precisionError //---------------------------------- /** * @private * Storage for the precisionError property. */ private var _precisionError:String; /** * @private */ private var precisionErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the value has a precision that exceeds the value * defined by the precision property. * * @default "The amount entered has too many digits beyond * the decimal point." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get precisionError():String { return _precisionError; } /** * @private */ public function set precisionError(value:String):void { precisionErrorOverride = value; _precisionError = value != null ? value : resourceManager.getString( "validators", "precisionError"); } //---------------------------------- // separationError //---------------------------------- /** * @private * Storage for the separationError property. */ private var _separationError:String; /** * @private */ private var separationErrorOverride:String; [Inspectable(category="Errors", defaultValue="null")] /** * Error message when the thousands separator is incorrectly placed. * * @default "The thousands separator must be followed by three digits." * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get separationError():String { return _separationError; } /** * @private */ public function set separationError(value:String):void { separationErrorOverride = value; _separationError = value != null ? value : resourceManager.getString( "validators", "separationError"); } //-------------------------------------------------------------------------- // // Overridden methods // //-------------------------------------------------------------------------- /** * @private */ override protected function resourcesChanged():void { super.resourcesChanged(); alignSymbol = alignSymbolOverride; allowNegative = allowNegativeOverride; currencySymbol = currencySymbolOverride; decimalSeparator = decimalSeparatorOverride; maxValue = maxValueOverride; minValue = minValueOverride; precision = precisionOverride; thousandsSeparator = thousandsSeparatorOverride; currencySymbolError = currencySymbolErrorOverride; decimalPointCountError = decimalPointCountErrorOverride; exceedsMaxError = exceedsMaxErrorOverride; invalidCharError = invalidCharErrorOverride; invalidFormatCharsError = invalidFormatCharsErrorOverride; lowerThanMinError = lowerThanMinErrorOverride; negativeError = negativeErrorOverride; precisionError = precisionErrorOverride; separationError = separationErrorOverride; } /** * Override of the base class doValidation() method * to validate a currency expression. * *

You do not call this method directly; * Flex calls it as part of performing a validation. * If you create a custom Validator class, you must implement this method.

* * @param value Object to validate. * * @return An Array of ValidationResult objects, with one ValidationResult * object for each field examined by the validator. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ override protected function doValidation(value:Object):Array { var results:Array = super.doValidation(value); // Return if there are errors // or if the required property is set to false and length is 0. var val:String = value ? String(value) : ""; if (results.length > 0 || ((val.length == 0) && !required)) return results; else return CurrencyValidator.validateCurrency(this, value, null); } } }