Number converter

Convert a JSF-formatted string value to/from a JavaScript™ number object. For example, the number converter converts the string "$ 1,000.00" (which might be the value of an input field) to a JavaScript number.

Effectively the JSF Number Converter is a JavaScript implementation of the Java™ DecimalFormat class.

The NumberConverter converts a string (often the value of a input field) to a JavaScript number object and vice versa. The conversion is controlled by a Java DecimalFormat pattern that describes the format of the number (e.g., the currency symbol, decimal point, grouping, negative sign).

Two Java DecimalFormat classes are supported -- the standard one in Java 1.4x/1.5x and the extended one provided in ICU4J. The ICU4J class is an extension (plus bug fixes) of the Java class.

The pattern used by a NumberConverter is "locale-neutral". The pattern uses "logical" markers that indicate where a decimal point is displayed, where a grouping symbol is displayed and so on. A separate attribute passed to the constructor specifies the locale-dependent symbols that are displayed in the field in the position(s) indicated by the logical markers in the pattern. For example, the pattern uses the . character (period character) to describe where the decimal point is displayed in a number. The locale separately specifies which character (e.g., a space character) is used as the decimal point when the value is converted to/from a string.

To as great a degree as is practical, the NumberConverter converts the numbers/strings using the same algorithm used by the Java NumberFormat class so that client-side and server-side conversions are the same.

The converter is used by other client side componentry such as the JSFBehaviorValidate, NumberAssist (keyboard assist for entering a number) and the client-side data caching. It can also be used directly a programmer who needs to "cast" a string containing a formatted number into a JavaScript Number object.

JavaScript constructor

hX_5.addConverter("id", new hX_5.NumberConverter(attributes)); where

id

The ID of the HTML tag to which the component is attached.

Attributes

Table 1. Number converter attributes

Attribute name

Description

pattern

The Java number pattern to use when converting this value.

ICU4J

If present (and not false), asterisk and plus will be parsed as pattern characters and secondary grouping symbols will be parsed in the pattern.

digits

If provided, the representation of the single character that represents a valid zero digit in the Unicode character set OTHER THAN the Western "0" character. This character and the following 9 characters in the Unicode character set will be output as "digits" when a value is formatted and will be parsed as digits when a value is converted from a string. This allows support for non-Western digits such as proper Arabic and/or Indic-Arabic digits. The value is the Unicode code point of this character expressed in decimal. For example, an Arabic zero is HEX 660, so 1632 should be the value of this attribute in this case.

locale

Locale information to be used when converting the value. As client JavaScript cannot access localization information on the machine, this information must be provided (usually it's derived on the server by using the client's locale information and using the Java DecimalFormatSymbols class).

The information is provided as a string of 6 or more characters of the format: GDMPINC where:

G

DecimalFormatSymbols.getGroupingSeparator (1 character). Grouping separator character, that is the "thousands separator". For example "," as in 1,000.

D

DecimalFormatSymbols.getDecimalSeparator (1 character). Decimal point character, for example, "." in 123.45
Note: If the format is a currency, DecimalFormatSymbols.getMonetaryDecimalSeparator is more appropriate.

P

DecimalFormatSymbols.getPercent (1 character). Percent character.

I

DecimalFormatSymbols.getPerMill (1 character). per mille symbol.

N

DecimalFormatSymbols.getMinusSign (1 character). Negative sign character, for example "-" in -3.0

C

DecimalFormatSymbols.getCurrencySymbol (String). Currency symbol, for example, $ (US)

For example " ,%‰-FR" means use space as the grouping separator, comma as the decimal symbol, percent sign as the percent symbol, use the mille sign as the mille symbol, use the minus sign as the negative symbol, and FR as the currency symbol. So if the format was "¤ #,##0.00", an example number would be "FR 1 23,45"

strict

Defines the strictness of the conversion when converting from a string to a number. The higher the value, the more exactly the value must conform to the pattern.

For numbers, currently strictness levels of 0 and 1 are equivalent. If the strictness is 2, if number is signed, the sign must be provided (otherwise it's assumed positive).

For more information on the Java Decimal Format number pattern, refer to http://java.sun.com/j2se/1.4.2/docs/api/java/text/DecimalFormat.html (when running without the ICU4J attribute set) and http://icu.sourceforge.net/apiref/icu4j/ (when ICU4J attribute is set). Synopsing the syntax, a pattern consists of a sequence of formatting characters where each character describes what is allowed at that position in a number. The basic formatting characters are:

0

A digit, if zero it is displayed.

#

A digit, if leading/trailing zero it is not displayed (it is suppressed).

.

Decimal separator or monetary decimal separator.

,

Grouping separator.

*

If ICU4J turned on, then the pad escape character. Marks where padding is done. The character that follows the * is used as the pad character.

E

Separates mantissa and exponent in scientific notation.

+

If ICU4J turned on, must follow E, if present means positive exponents are shown with a plus sign before the exponent.

;

Subpattern boundary marker. The sub-pattern before the ; defines a positive value and the sub-pattern after the ; defines a negative value.

/

JSF extension marker. If present, follows the last subpattern. See below for usage.

Note that the ICU4J symbols 1-9 (rounding) and @ (significant digits) are not supported.

The pattern consists of a sequence of 0 and # symbols which define the maximum number of digits in the number. # symbols denote a digit which is suppressed if it is a leading/trailing zero. 0 symbols denote a digit which is not suppressed. # symbols must precede any 0 symbols to the left of the decimal point and follow them to the right of the decimal point (e.g., #0# is not allowed). The decimal symbol marks the position where the (localized) decimal is shown. The thousands marker defines where the localized grouping symbol is shown (if a grouping character is provided, the first "group" to the left of the decimal point defines the grouping pattern used throughout). If ICU4J is turned on, up to two thousands markers are used (instead of one), where the two symbols mark the primary and secondary groupings (in all non-Indic languages, if two markers are provided, they should have the same grouping (e.g. 3 digits), in Indic they may designate different groupings). An exponential marker indicates this number uses exponential format. If a pair of patterns is provided (using the subpattern boundary marker), then the first pattern defines a positive value while the second one defines a negative value. If the number is in exponential format, a plus sign may follow the E (only valid position) indicating that the exponent is always shown with a sign (plus or minus).

For example, the pattern "###" means the number consists of at most three digits with leading zeroes suppressed. The pattern ##0.00 means the number consists of at most three digits, a decimal and two fractional digits where the fractional digits are always displayed. The pattern ###,###,##0.00 means up to 9 digits are displayed to the left of the decimal point with grouping (thousands) separators every 3 decimal places. At least one digit is always present to the left of the decimal point (further leading zeroes suppressed) and two digits are always displayed to the right of the decimal point.

Any other character may be added to the pattern as a literal prefix or a suffix. For example $ ### means that the literal characters "$ " will be displayed before the number. In the prefix/suffix, the following characters have special meaning:

'

Used to quote special characters in a prefix or suffix, for example, "'#'#" formats 123 to "#123". To create a single quote itself, use two in a row: "# o''clock".

%

The number is treated as a percent (1/100th) that is, it's multiplied by 100 and the percent sign shown at this position.

The number is treated as a 1 thousandth (mille) that is, it's multiplied by 1000 and the mille symbol is shown at this position.

¤

The currency symbol specified in the locale information is displayed in this location.

NOTE the Java restriction that these symbols (excepting quote) should only appear in either the left or right prefix but not both.

There are two ways padding may be added to a value. if ICU4J is turned on, an asterisk may be inserted before the prefix OR immediately after the prefix OR immediately before the suffix OR at the end of the subpattern. The asterisk is followed by the character which is to be used to pad the value. The value is padded to its maximum width by inserting the pad character at the marked position. The maximum width is determined by counting the width of the prefix, suffix, digit characters, decimal point and thousands markers in the positive pattern.

JSF also extends the standard Java number pattern to handle specifying padding on both sides of the decimal point. If the JSF extension marker is found after the last subpattern, then the characters following the marker are interpreted as follows:
  • If one character follows the marker and a number has leading zeroes (that is there are leading 0 characters in the pattern), instead of displaying leading zeroes, the provided character is displayed in lieu of each zero.
  • If two characters follow the marker and a number has leading and/or trailing zeroes (that is there are leading and/or trailing 0 characters in the pattern), instead of displaying these zeroes, the first provided character is displayed in lieu of each leading zero and the second character is displayed in lieu of each trailing zero. If the value is zero, the decimal point is replaced by the first character.

In other words these extensions are used to "pad" a number (using the supplied characters). For example 000/* applied to the value 1 will display **1.

API calls

Table 2. API calls

API call

Description

number = stringToValue(string)

Converts a string to a JavaScript number object. Returns null if fails.

string = valueToString(number)

Converts a JavaScript number to a string. Returns null if fails.

string = lastError()

If a conversion fails, returns the reason for the failure as a localized string.

object = setAttribute(attribute)

Sets an attribute or changes its value (if it was set previously).

string = getAttribute(attribute-name)

Retrieves the current value of an attribute.

Limitations

Example code

Convert the value of an input field to a JavaScript number, add one to it and store back the result.

// Construct the converter with a pattern of $ ###,##0.00;($ ###,##0.00)
hX.addConverter("AZ0", new hX.NumberConverter("pattern:$ ###,##0.00;($ ###,##0.00)", 
                  "strict:2", "locale:,.%‰-$"));

// Convert the value of an input field from a string formatted using this pattern to a JS number
var x = document.getElementById("form1:text0");
var cvt = hX.getConverterById("AZ0");
var num = cvt.stringToValue(x.value);

// Check for errors
if (num==null)
    alert ("ERROR: " + cvt.lastError());

// Increment the value and put it back
else {
    num++;
    x.value = cvt.valueToString(num);

As above, but allow Arabic-Indic digits, specify two thousands groupings and pad the value after the currency symbol using ICU4J padding.

// Construct the converter with asterisk as the pad character and alternating grouping
hX.addConverter("AZ0", new hX.NumberConverter("ICU4J", "digits:1632", 
                  "pattern:$ **###,##,##0.00;($ ###,##0.00)", "strict:2", "locale:,.%‰-$"));
Related tasks
Adding input components to a Faces JSP page

Feedback