Custom formatters

Flex includes several predefined formatters that you can use in your applications to format data. You also might have to extend the functionality of these predefined formatters, or create formatters for your specific application needs.

For more information on using formatters, see Formatting Data.

Creating a custom formatter

You create a custom formatter by creating a class that extends the mx.formatters.Formatter base class, or by creating a class that extends one of the standard formatter classes, which all extend mx.formatters.Formatter. The following example shows the class hierarchy for formatters:

The class hierarchy for formatters

Like standard formatter classes, your custom formatter class must contain a public format() method that takes a single argument and returns a String that contains the formatted data. Most of the processing of your custom formatter occurs within the format() method.

Your custom formatter also might let the user specify which pattern formats the data. Where applicable, the Flex formatters, such as the ZipCodeFormatter, use a formatString property to pass a format pattern. Some Flex formatters, such as the NumberFormatter and CurrencyFormatter classes, do not have formatString properties, because they use a set of properties to configure formatting.

Creating a simple formatter

This example defines a simple formatter class that converts any String to all uppercase or all lowercase letters depending on the value passed to the formatString property. By default, the formatter converts a String to all uppercase.

package myFormatters 
{ 
    // formatters/myFormatter/SimpleFormatter.as 
    import mx.formatters.Formatter 
    import mx.formatters.SwitchSymbolFormatter 
 
    public class SimpleFormatter extends Formatter 
    { 
        // Declare the variable to hold the pattern string. 
        public var myFormatString:String = "upper"; 
 
        // Constructor 
        public function SimpleFormatter() { 
            // Call base class constructor. 
            super(); 
        } 
 
        // Override format(). 
        override public function format(value:Object):String { 
            // 1. Validate value - must be a nonzero length string. 
            if( value.length == 0) 
                {   error="0 Length String"; 
                    return "" 
                } 
 
            // 2. If the value is valid, format the string. 
            switch (myFormatString) { 
                case "upper" : 
                    var upperString:String = value.toUpperCase(); 
                    return upperString; 
                    break; 
                case "lower" : 
                    var lowerString:String = value.toLowerCase(); 
                    return lowerString; 
                    break; 
                default :   
                    error="Invalid Format String"; 
                    return "" 
            } 
        } 
    } 
}

You can use this formatter in an application, as the following example shows:

<?xml version="1.0" ?> 
<!-- createcomps_formatters/FormatterSimple.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myFormatters.*"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Declarations> 
        <!-- Declare a formatter and specify formatting properties. --> 
        <MyComp:SimpleFormatter id="upperFormat" myFormatString="upper" /> 
    </fx:Declarations> 
 
    <!-- Trigger the formatter while populating a string with data. --> 
    <mx:TextInput id="myTI" /> 
    
    <mx:TextArea text="Your uppercase string is {upperFormat.format(myTI.text)}" /> 
</s:Application>

The namespace declaration in the <s:Application> tag specifies to use the MyComp prefix when referencing the formatter, and the location of the formatter's ActionScript file. That file is in the myFormatters subdirectory of the application, or in the default classpath of the application. For more information on deploying your formatters, see Component compilation.

Handling errors in formatters

For all formatter classes, except for the SwitchSymbolFormatter class, when an error occurs, the formatter returns an empty string and writes a string that describes the error condition to the formatter's error property. The error property is inherited from the Formatter superclass.

In your application, you can test for an empty string in the result returned by the formatter. If detected, you can check the error property to determine the cause of the error. For an example that handles a formatter error, see Formatting Data. For more information on the SwitchSymbolFormatter class, see Using the SwitchSymbolFormatter class.

Using the SwitchSymbolFormatter class

You can use the SwitchSymbolFormatter utility class when you create custom formatters. You use this class to replace placeholder characters in one string with numbers from a second string.

For example, you specify the following information to the SwitchSymbolFormatter class:

Format string

The Social Security number is: ###-##-####"

Input string

 "123456789"

The SwitchSymbolFormatter class parses the format string and replaces each placeholder character with a number from the input string in the order in which the numbers are specified in the input string. The default placeholder character is the number sign (#). You can define a different placeholder character by passing it to the constructor when you create a SwitchSymbolFormatter object. For an example, see Using a different placeholder character.

The SwitchSymbolFormatter class creates the following output string from the Format and Input strings:

"The Social Security number is: 123-45-6789"
You pass the format string and input string to the SwitchSymbolFormatter.formatValue() method to create the output string, as the following example shows:
<?xml version="1.0" ?> 
<!-- createcomps_formatters/FormatterSwitchSymbol.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
  <fx:Script> 
    <![CDATA[ 
        
      import mx.formatters.SwitchSymbolFormatter; 
 
      // Event handler to validate and format input.            
      private function formatVal():void { 
          
        var switcher:SwitchSymbolFormatter=new SwitchSymbolFormatter('#'); 
 
        formattedSCNumber.text = 
          switcher.formatValue("Formatted Social Securty number: ###-##-#### ", scNum.text); 
      } 
    ]]> 
  </fx:Script> 
 
    <mx:Label 
        text="Enter a 9 digit Social Security number with no separator characters:"/> 
    <mx:TextInput id="scNum" 
        text="" 
        maxChars="9" width="50%"/> 
 
  <mx:Button label="Format" 
      click="formatVal();"/> 
  <mx:TextInput id="formattedSCNumber" 
      editable="false" width="75%"/> 
</s:Application>

You can mix alphanumeric characters and placeholder characters in this format string. The format string can contain any characters that are constant for all values of the numeric portion of the string. However, the input string for formatting must be numeric. The number of digits supplied in the source value must match the number of digits defined in the format string.

Using a different placeholder character

By default, the SwitchSymbolFormatter class uses a number sign (#) as the placeholder character to indicate a number substitution within its format string. However, sometimes you might want to include a number sign in your actual format string. Then, you must use a different symbol to indicate a number substitution slot within the format string. You can select any character for this alternative symbol as long as it doesn't appear in the format string.

For example, to use the ampersand character (&) as the placeholder, you create an instance of the SwitchSymbolFormatter class, as the following example shows:

 var dataFormatter = new SwitchSymbolFormatter("&");

Handling errors with the SwitchSymbolFormatter class

Unlike other formatters, the SwitchSymbolFormatter class does not write its error messages into an error property. Instead, it is your responsibility to test for error conditions and return an error message if appropriate.

The custom formatter component in the following example formats nine-digit Social Security numbers by using the SwitchSymbolFormatter class:

package myFormatters 
{ 
    // formatters/myFormatter/CustomSSFormatter.as 
    import mx.formatters.Formatter 
    import mx.formatters.SwitchSymbolFormatter 
 
    public class CustomSSFormatter extends Formatter 
    { 
        // Declare the variable to hold the pattern string. 
        public var formatString : String = "###-##-####"; 
 
        // Constructor 
        public function CustomSSFormatter() { 
            // Call base class constructor. 
            super(); 
        } 
 
        // Override format(). 
        override public function format( value:Object ):String { 
            // Validate input string value - must be a 9-digit number. 
            // You must explicitly check if the value is a number. 
            // The formatter does not do that for you. 
            if( !value  || value.toString().length != 9) 
                {   error="Invalid String Length"; 
                    return "" 
                } 
 
            // Validate format string. 
            // It must contain 9 number placeholders. 
            var numCharCnt:int = 0; 
            for( var i:int = 0; i<formatString.length; i++ ) 
                { 
                    if( formatString.charAt(i) == "#" ) 
                    {   numCharCnt++; 
                    } 
                } 
 
            if( numCharCnt != 9 ) 
            { 
                error="Invalid Format String"; 
                return "" 
            } 
 
            // If the formatString and value are valid, format the number. 
            var dataFormatter:SwitchSymbolFormatter = 
                new SwitchSymbolFormatter(); 
            return dataFormatter.formatValue( formatString, value ); 
        } 
    } 
}

The following example uses this custom formatter in an application:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- createcomps_formatters/FormatterSS.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myFormatters.*"> 
    <fx:Declarations> 
        <!-- Declare a formatter and specify formatting properties. --> 
        <MyComp:CustomSSFormatter id="SSFormat" 
            formatString="SS: #-#-#-#-#-#-#-#-#"/> 
    </fx:Declarations> 
 
    <!-- Trigger the formatter while populating a string with data. --> 
    <mx:TextInput text="Your SS number is {SSFormat.format('123456789')}"/> 
</s:Application>

Extending a Formatter class

You can extend the Formatter class to create a custom formatter, or any formatter class. The example in this section extends the ZipCodeFormatter class by allowing an extra format pattern: "#####*####".

In this example, if the user omits a format string, or specifies the default value of "#####*####", the formatter returns the ZIP code using the format "#####*####". If the user specifies any other format string, such as a five-digit string in the form "#####", the custom formatter calls the format() method in the superclass ZipCodeFormatter class to format the data.

package myFormatters 
{ 
    // formatters/myFormatter/ExtendedZipCodeFormatter.as 
    import mx.formatters.Formatter 
    import mx.formatters.ZipCodeFormatter 
    import mx.formatters.SwitchSymbolFormatter 
 
    public class ExtendedZipCodeFormatter extends ZipCodeFormatter { 
 
        // Constructor 
        public function ExtendedZipCodeFormatter() { 
            // Call base class constructor. 
            super(); 
            // Initialize formatString. 
            formatString = "#####*####"; 
        } 
 
        // Override format(). 
        override public function format(value:Object):String { 
            // 1. If the formatString is our new pattern, 
            // then validate and format it. 
 
            if( formatString == "#####*####" ){ 
 
                if( String( value ).length == 5 ) 
                    value = String( value ).concat("0000"); 
 
                if( String( value ).length == 9 ){ 
                    var dataFormatter:SwitchSymbolFormatter = 
                        new SwitchSymbolFormatter(); 
                    return dataFormatter.formatValue( formatString, value ); 
                } 
                else { 
                    error="Invalid String Length"; 
                    return "" 
                    } 
                } 
 
            // If the formatString is anything other than '#####*####, 
            // call super and validate and format as usual using 
            // the base ZipCodeFormatter. 
            return super.format(value); 
        } 
    }   
}

Notice that the ExtendedZipCodeFormatter class did not have to define a formatString property because it is already defined in its base class, ZipCodeFormatter.

The following example uses this custom formatter in an application:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- createcomps_formatters/FormatterZC.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:MyComp="myFormatters.*"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Declarations> 
        <!-- Declare a formatter and specify formatting properties. --> 
        <MyComp:ExtendedZipCodeFormatter id="ZipCodeFormat"/> 
    </fx:Declarations> 
 
    <!-- Trigger the formatter while populating a string with data. --> 
    <mx:TextInput width="220" 
        text="Your zipcode number is {ZipCodeFormat.format('123456789')}"/> 
</s:Application>

Navigation

Using Flex » Custom components

Adobe and Adobe Flash Platform are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.