blob: e20ae92354958a05f9061bea43021be758b97eec [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta name="DC.Type" content="topic"/>
<meta name="DC.Title" content="Custom formatters"/>
<meta name="DC.Format" content="XHTML"/>
<meta name="DC.Identifier" content="WS2db454920e96a9e51e63e3d11c0bf69084-7a04_verapache"/>
<title>Custom formatters</title>
</head>
<body id="WS2db454920e96a9e51e63e3d11c0bf69084-7a04_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7a04_verapache"><!-- --></a>
<div>
<p>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. </p>
<p>For more information on using formatters, see <a href="flx_formatters_fm.html#WS2db454920e96a9e51e63e3d11c0bf69084-7fef_verapache">Formatting
Data</a>.</p>
</div>
<div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf68b24-7ff9_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf68b24-7ff9_verapache"><!-- --></a>
<h2 class="topictitle2">Creating a custom formatter</h2>
<div>
<p>You
create a custom formatter by creating a class that extends the <a href="https://flex.apache.org/asdoc/mx/formatters/Formatter.html" target="_blank">mx.formatters.Formatter</a> 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:</p>
<div class="figborder">
<img src="images/cf_hierarchy_class_formatters.png" alt="The class hierarchy for formatters"/>
</div>
<p>Like standard formatter classes, your custom formatter class
must contain a public <samp class="codeph">format()</samp> 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 <samp class="codeph">format()</samp> method. </p>
<p>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 <samp class="codeph">formatString</samp> property
to pass a format pattern. Some Flex formatters, such as the NumberFormatter
and CurrencyFormatter classes, do not have <samp class="codeph">formatString</samp> properties,
because they use a set of properties to configure formatting.</p>
</div>
<div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf68b24-7fff_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf68b24-7fff_verapache"><!-- --></a>
<h3 class="topictitle3">Creating a simple formatter</h3>
<div>
<p>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 <samp class="codeph">formatString</samp> property.
By default, the formatter converts a String to all uppercase.</p>
<pre class="codeblock">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 ""
}
}
}
}</pre>
<p>You can use this formatter in an application, as the following
example shows:</p>
<pre class="codeblock">&lt;?xml version="1.0" ?&gt;
&lt;!-- createcomps_formatters/FormatterSimple.mxml --&gt;
&lt;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.*"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Declarations&gt;
&lt;!-- Declare a formatter and specify formatting properties. --&gt;
&lt;MyComp:SimpleFormatter id="upperFormat" myFormatString="upper" /&gt;
&lt;/fx:Declarations&gt;
&lt;!-- Trigger the formatter while populating a string with data. --&gt;
&lt;mx:TextInput id="myTI" /&gt;
&lt;mx:TextArea text="Your uppercase string is {upperFormat.format(myTI.text)}" /&gt;
&lt;/s:Application&gt;</pre>
<p>The namespace declaration in the <samp class="codeph">&lt;s:Application&gt;</samp> tag
specifies to use the <samp class="codeph">MyComp</samp> 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 <a href="flx_compiledeploy_cd.html#WS2db454920e96a9e51e63e3d11c0bf69084-79bd_verapache">Component
compilation</a>.</p>
</div>
</div>
<div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffb_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffb_verapache"><!-- --></a>
<h3 class="topictitle3">Handling errors in formatters</h3>
<div>
<p>For
all formatter classes, except for the <a href="https://flex.apache.org/asdoc/mx/formatters/SwitchSymbolFormatter.html" target="_blank">SwitchSymbolFormatter</a> class,
when an error occurs, the formatter returns an empty string and
writes a string that describes the error condition to the formatter's <samp class="codeph">error</samp> property.
The <samp class="codeph">error</samp> property is inherited from the <a href="https://flex.apache.org/asdoc/mx/formatters/Formatter.html" target="_blank">Formatter</a> superclass.</p>
<p>In your application, you can test for an empty string in the
result returned by the formatter. If detected, you can check the <samp class="codeph">error</samp> property
to determine the cause of the error. For an example that handles
a formatter error, see <a href="flx_formatters_fm.html#WS2db454920e96a9e51e63e3d11c0bf69084-7fef_verapache">Formatting
Data</a>. For more information on the SwitchSymbolFormatter class,
see <a href="flx_createformatters_cf.html#WS2db454920e96a9e51e63e3d11c0bf69084-79ba_verapache">Using
the SwitchSymbolFormatter class</a>.</p>
</div>
</div>
</div>
<div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-79ba_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-79ba_verapache"><!-- --></a>
<h2 class="topictitle2">Using the SwitchSymbolFormatter
class</h2>
<div>
<p>You can use the <a href="https://flex.apache.org/asdoc/mx/formatters/SwitchSymbolFormatter.html" target="_blank">SwitchSymbolFormatter</a> utility
class when you create custom formatters. You use this class to replace
placeholder characters in one string with numbers from a second
string. </p>
<p>For example, you specify the following information to the SwitchSymbolFormatter
class: </p>
<dl>
<dt class="dlterm">Format string</dt>
<dd>
<p>The Social Security number is: ###-##-####" </p>
</dd>
<dt class="dlterm">Input string</dt>
<dd>
<p> "123456789"</p>
</dd>
</dl>
<p>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 <a href="flx_createformatters_cf.html#WS2db454920e96a9e51e63e3d11c0bf69084-79b9_verapache">Using
a different placeholder character</a>. </p>
<p>The SwitchSymbolFormatter class creates the following output
string from the Format and Input strings:</p>
<pre class="codeblock">"The Social Security number is: 123-45-6789"</pre>
<div class="p">You pass the format string and input string to the SwitchSymbolFormatter.formatValue()
method to create the output string, as the following example shows: <pre class="codeblock">&lt;?xml version="1.0" ?&gt;
&lt;!-- createcomps_formatters/FormatterSwitchSymbol.mxml --&gt;
&lt;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"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![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);
}
]]&gt;
&lt;/fx:Script&gt;
&lt;mx:Label
text="Enter a 9 digit Social Security number with no separator characters:"/&gt;
&lt;mx:TextInput id="scNum"
text=""
maxChars="9" width="50%"/&gt;
&lt;mx:Button label="Format"
click="formatVal();"/&gt;
&lt;mx:TextInput id="formattedSCNumber"
editable="false" width="75%"/&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>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. </p>
</div>
<div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf69084-79b9_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-79b9_verapache"><!-- --></a>
<h3 class="topictitle3">Using a different placeholder character</h3>
<div>
<p>By default, the <a href="https://flex.apache.org/asdoc/mx/formatters/SwitchSymbolFormatter.html" target="_blank">SwitchSymbolFormatter</a> 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.</p>
<p>For example, to use the ampersand character (&amp;) as the placeholder,
you create an instance of the SwitchSymbolFormatter class, as the
following example shows:</p>
<pre class="codeblock"> var dataFormatter = new SwitchSymbolFormatter("&amp;");</pre>
</div>
</div>
<div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffe_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffe_verapache"><!-- --></a>
<h3 class="topictitle3">Handling errors with the SwitchSymbolFormatter
class</h3>
<div>
<p>Unlike other formatters, the <a href="https://flex.apache.org/asdoc/mx/formatters/SwitchSymbolFormatter.html" target="_blank">SwitchSymbolFormatter</a> class
does not write its error messages into an <samp class="codeph">error</samp> property.
Instead, it is your responsibility to test for error conditions
and return an error message if appropriate.</p>
<p>The custom formatter component in the following example formats
nine-digit Social Security numbers by using the SwitchSymbolFormatter
class:</p>
<pre class="codeblock">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&lt;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 );
}
}
}</pre>
<p>The following example uses this custom formatter in an application:</p>
<pre class="codeblock">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!-- createcomps_formatters/FormatterSS.mxml --&gt;
&lt;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.*"&gt;
&lt;fx:Declarations&gt;
&lt;!-- Declare a formatter and specify formatting properties. --&gt;
&lt;MyComp:CustomSSFormatter id="SSFormat"
formatString="SS: #-#-#-#-#-#-#-#-#"/&gt;
&lt;/fx:Declarations&gt;
&lt;!-- Trigger the formatter while populating a string with data. --&gt;
&lt;mx:TextInput text="Your SS number is {SSFormat.format('123456789')}"/&gt;
&lt;/s:Application&gt;</pre>
</div>
</div>
</div>
<div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffa_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf68b24-7ffa_verapache"><!-- --></a>
<h2 class="topictitle2">Extending a Formatter class</h2>
<div>
<p>You can extend the <a href="https://flex.apache.org/asdoc/mx/formatters/Formatter.html" target="_blank">Formatter</a> class
to create a custom formatter, or any formatter class. The example
in this section extends the <a href="https://flex.apache.org/asdoc/mx/formatters/ZipCodeFormatter.html" target="_blank">ZipCodeFormatter</a> class
by allowing an extra format pattern: "#####*####".</p>
<p>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 <samp class="codeph">format()</samp> method in the superclass ZipCodeFormatter
class to format the data. </p>
<pre class="codeblock">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);
}
}
}</pre>
<p>Notice that the ExtendedZipCodeFormatter class did not have to
define a <samp class="codeph">formatString</samp> property because it is already
defined in its base class, ZipCodeFormatter. </p>
<p>The following example uses this custom formatter in an application:</p>
<pre class="codeblock">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!-- createcomps_formatters/FormatterZC.mxml --&gt;
&lt;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.*"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Declarations&gt;
&lt;!-- Declare a formatter and specify formatting properties. --&gt;
&lt;MyComp:ExtendedZipCodeFormatter id="ZipCodeFormat"/&gt;
&lt;/fx:Declarations&gt;
&lt;!-- Trigger the formatter while populating a string with data. --&gt;
&lt;mx:TextInput width="220"
text="Your zipcode number is {ZipCodeFormat.format('123456789')}"/&gt;
&lt;/s:Application&gt;</pre>
<p/>
</div>
<div>
<p><strong>Navigation</strong></p>
<p><a href="index.html">Using Flex</a> &raquo; <a href="flx_p8a_custom_components.html">Custom components</a></p>
</div>
<p>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.</p>
</div>
</body>
</html>