//////////////////////////////////////////////////////////////////////////////// // // 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.formatters { import mx.managers.ISystemManager; import mx.managers.SystemManager; [ResourceBundle("formatters")] [ResourceBundle("SharedResources")] [Alternative(replacement="spark.formatters.NumberFormatter", since="4.5")] /** * The NumberFormatter class formats a valid number * by adjusting the decimal rounding and precision, * the thousands separator, and the negative sign. * *
If you use both the rounding
and precision
* properties, rounding is applied first, and then you set the decimal length
* by using the specified precision
value.
* This lets you round a number and still have a trailing decimal;
* for example, 303.99 = 304.00.
If an error occurs, an empty String is returned and a String
* describing the error is saved to the error
property.
* The error
property can have one of the following values:
"Invalid value"
means an invalid numeric value is passed to
* the format()
method. The value should be a valid number in the
* form of a Number or a String."Invalid format"
means one of the parameters
* contain an unusable setting.The <mx:NumberFormatter>
tag
* inherits all of the tag attributes of its superclass,
* and adds the following tag attributes:
* <mx:NumberFormatter * decimalSeparatorFrom="." * decimalSeparatorTo="." * precision="-1" * rounding="none|up|down|nearest" * thousandsSeparatorFrom="," * thousandsSeparatorTo="," * useNegativeSign="true|false" * useThousandsSeparator="true|false"/> ** * @includeExample examples/NumberFormatterExample.mxml * * @see mx.formatters.NumberBase * @see mx.formatters.NumberBaseRoundType * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class NumberFormatter extends Formatter { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function NumberFormatter() { super(); } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // decimalSeparatorFrom //---------------------------------- /** * @private * Storage for the decimalSeparatorFrom property. */ private var _decimalSeparatorFrom:String; /** * @private */ private var decimalSeparatorFromOverride:String; [Inspectable(category="General", defaultValue="null")] /** * Decimal separator character to use * when parsing an input String. * *
When setting this property, ensure that the value of the
* thousandsSeparatorFrom
property does not equal this property.
* Otherwise, an error occurs when formatting the value.
When setting this property, ensure that the value of the
* thousandsSeparatorTo
property does not equal this property.
* Otherwise, an error occurs when formatting the value.
-1
.
* A value of -1
means do not change the precision. For example,
* if the input value is 1.453 and rounding
* is set to NumberBaseRoundType.NONE
, return a value of 1.453.
* If precision
is -1
and you have set some form of
* rounding, return a value based on that rounding type.
*
* @default -1
*
* @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(
"formatters", "numberFormatterPrecision");
}
//----------------------------------
// rounding
//----------------------------------
/**
* @private
* Storage for the rounding property.
*/
private var _rounding:String;
/**
* @private
*/
private var roundingOverride:String;
[Inspectable(category="General", enumeration="none,up,down,nearest", defaultValue="null")]
// !!@ Should enumeration include null?
/**
* Specifies how to round the number.
*
* In ActionScript, you can use the following constants to set this property:
* NumberBaseRoundType.NONE
, NumberBaseRoundType.UP
,
* NumberBaseRoundType.DOWN
, or NumberBaseRoundType.NEAREST
.
* Valid MXML values are "down", "nearest", "up", and "none".
When setting this property, ensure that the value of the
* decimalSeparatorFrom
property does not equal this property.
* Otherwise, an error occurs when formatting the value.
When setting this property, ensure that the value of the
* decimalSeparatorTo
property does not equal this property.
* Otherwise, an error occurs when formatting the value.
true
, format a negative number
* by preceding it with a minus "-" sign.
* If false
, format the number
* surrounded by parentheses, for example (400).
*
* @default true
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get useNegativeSign():Object
{
return _useNegativeSign;
}
/**
* @private
*/
public function set useNegativeSign(value:Object):void
{
useNegativeSignOverride = value;
_useNegativeSign = value != null ?
Boolean(value) :
resourceManager.getBoolean(
"formatters", "useNegativeSignInNumber");
}
//----------------------------------
// useThousandsSeparator
//----------------------------------
/**
* @private
* Storage for the useThousandsSeparator property.
*/
private var _useThousandsSeparator:Object;
/**
* @private
*/
private var useThousandsSeparatorOverride:Object;
[Inspectable(category="General", defaultValue="null")]
/**
* If true
, split the number into thousands increments
* by using a separator character.
*
* @default true
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get useThousandsSeparator():Object
{
return _useThousandsSeparator;
}
/**
* @private
*/
public function set useThousandsSeparator(value:Object):void
{
useThousandsSeparatorOverride = value;
_useThousandsSeparator = value != null ?
Boolean(value) :
resourceManager.getBoolean(
"formatters", "useThousandsSeparator");
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function resourcesChanged():void
{
super.resourcesChanged();
decimalSeparatorFrom = decimalSeparatorFromOverride;
decimalSeparatorTo = decimalSeparatorToOverride;
precision = precisionOverride;
rounding = roundingOverride;
thousandsSeparatorFrom = thousandsSeparatorFromOverride;
thousandsSeparatorTo = thousandsSeparatorToOverride;
useNegativeSign = useNegativeSignOverride;
useThousandsSeparator = useThousandsSeparatorOverride;
}
/**
* Formats the number as a String.
* If value
cannot be formatted, return an empty String
* and write a description of the error to the error
property.
*
* @param value Value to format.
*
* @return Formatted String. Empty if an error occurs.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function format(value:Object):String
{
// Reset any previous errors.
if (error)
error = null;
if (useThousandsSeparator &&
((decimalSeparatorFrom == thousandsSeparatorFrom) ||
(decimalSeparatorTo == thousandsSeparatorTo)))
{
error = defaultInvalidFormatError;
return "";
}
if (decimalSeparatorTo == "" || !isNaN(Number(decimalSeparatorTo)))
{
error = defaultInvalidFormatError;
return "";
}
var dataFormatter:NumberBase = new NumberBase(decimalSeparatorFrom,
thousandsSeparatorFrom,
decimalSeparatorTo,
thousandsSeparatorTo);
// -- value --
if (value is String)
value = dataFormatter.parseNumberString(String(value));
if (value === null || isNaN(Number(value)))
{
error = defaultInvalidValueError;
return "";
}
// -- format --
var isNegative:Boolean = (Number(value) < 0);
var numStr:String = value.toString();
numStr.toLowerCase();
var e:int = numStr.indexOf("e");
if (e != -1) //deal with exponents
numStr = dataFormatter.expandExponents(numStr);
var numArrTemp:Array = numStr.split(".");
var numFraction:int = numArrTemp[1] ? String(numArrTemp[1]).length : 0;
if (precision <= numFraction)
{
if (rounding != NumberBaseRoundType.NONE)
{
numStr = dataFormatter.formatRoundingWithPrecision(
numStr, rounding, int(precision));
}
}
var numValue:Number = Number(numStr);
if (Math.abs(numValue) >= 1)
{
numArrTemp = numStr.split(".");
var front:String = useThousandsSeparator ?
dataFormatter.formatThousands(String(numArrTemp[0])) :
String(numArrTemp[0]);
if (numArrTemp[1] != null && numArrTemp[1] != "")
numStr = front + decimalSeparatorTo + numArrTemp[1];
else
numStr = front;
}
else if (Math.abs(numValue) > 0)
{
// Check if the string is in scientific notation
if (numStr.indexOf("e") != -1)
{
var temp:Number = Math.abs(numValue) + 1;
numStr = temp.toString();
}
numStr = decimalSeparatorTo +
numStr.substring(numStr.indexOf(".") + 1);
}
numStr = dataFormatter.formatPrecision(numStr, int(precision));
// If our value is 0, then don't show -0
if (Number(numStr) == 0)
{
isNegative = false;
}
if (isNegative)
numStr = dataFormatter.formatNegative(numStr, useNegativeSign);
if (!dataFormatter.isValid)
{
error = defaultInvalidFormatError;
return "";
}
return numStr;
}
}
}