实际上,JSF 数字转换器是 Java™ DecimalFormat 类的 JavaScript 实现。
数字转换器可将字符串(通常是输入字段的值)转换为 JavaScript 数字对象,或将相应的数字对象转换为字符串。该转换由描述数字的格式(例如,货币符号、小数点、分组符号和负号)的 Java 十进制格式模式进行控制。
支持两个 Java DecimalFormat 类 - Java 1.4x/1.5x 中的标准 DecimalFormat 类和 ICU4J 中提供的扩展 DecimalFormat 类。ICU4J 类是 Java 类的扩展和错误修订。
数字转换器使用的模式与“语言环境无关”。该模式使用“逻辑”标记来指示小数点的显示位置以及分组符号的显示位置等。可通过传递至构造函数的单独属性指定随语言环境而定的符号,这些符号会显示在字段中由模式内的逻辑标记所指示的位置。例如,该模式使用 . 字符(句点字符)来描述小数点在数字中的显示位置。在值与字符串之间进行转换时,语言环境单独指定了用作小数点的字符,例如,空格字符。
为了最大程度地与实际情况相吻合,数字转换器使用 Java NumberFormat 类所使用的算法来转换数字/字符串,以便客户端和服务器端转换相同。
此转换器可供其他客户端组件使用,例如,JSFBehaviorValidate、数字辅助(用于输入数字的键盘辅助)以及客户端数据高速缓存。如果程序员需要将包含已格式化数字的字符串“强制转换”为 JavaScript 数字对象,则也可以直接使用此转换器。
hX_5.addConverter("id", new hX_5.NumberConverter(attributes)); 其中
id |
组件所连接至的 HTML 标记的 ID。 |
属性名称 |
描述 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
pattern |
转换此值时要使用的 Java 数字模式。 |
||||||||||||
ICU4J |
如果存在且不为 false,则星号和加号将作为模式字符来解析,而辅助分组符号将在该模式中进行解析。 |
||||||||||||
digits |
如果提供,则表示 Unicode 字符集中有效零数字(而不是西文字符“0”)的单字符。如果对值进行格式化,则 Unicode 字符集中的此字符和后续 9 个字符将作为“数字”来输出。如果此值是从字符串转换的,则这些字符将解析为数字。这对于非西文数字同样适用,例如,正确的阿拉伯数字和/或印度-阿拉伯数字。值是此字符(以十进制表示)的 Unicode 代码点。例如,阿拉伯数字 0 是十六进制 660,因此在这种情况下,1632 应该是此属性的值。 |
||||||||||||
locale |
转换值时要使用的语言环境信息。由于客户机 JavaScript 不能访问机器上的本地化信息,所以必须提供此信息。通常,在服务器上通过使用客户机的语言环境信息和使用 Java DecimalFormatSymbols 类来取得此信息。 以包含 6 个或更多字符的字符串的形式来提供此信息,格式为:GDMPINC,其中:
例如,“ ,%‰-FR”表示使用空格作为分组分隔符,逗号作为小数点符号,百分号作为百分比符号,千分号作为千分比符号,减号作为负号以及 FR 作为货币符号。因此,如果格式为“¤ #,##0.00”,则示例数字为“FR 1 23,45” |
||||||||||||
strict |
定义从字符串转换为数字时转换的精确性。精确性越高,值就必须更准确地符合模式。 对于数字,0 和 1 级别的当前精确性是等价的。如果精确性为 2,数字为带符号数,则必须提供符号,否则将假定数字为正数。 |
有关 Java 十进制格式数字模式的更多信息,请参阅在未设置 ICU4J 属性时运行的 http://java.sun.com/j2se/1.4.2/docs/api/java/text/DecimalFormat.html以及在设置 ICU4J 属性时运行的 http://icu.sourceforge.net/apiref/icu4j/。对语法进行了概括,模式包含一系列格式化字符,其中每个字符描述在数字中的相应位置所允许使用的内容。基本格式化字符包括:
0 |
数字,如果为零,则显示。 |
# |
数字,如果为前导零/结尾零,则不显示(被抑制)。 |
. |
十进制分隔符或货币十进制分隔符。 |
, |
分组分隔符。 |
* |
如果打开了 ICU4J,则填充转义字符。对完成填充的位置进行标记。紧随 * 的字符,用作填充字符。 |
E |
区分科学计数法中的尾数和指数。 |
+ |
如果打开了 ICU4J,则必须后加 E。如果存在,则表示一个正指数,即在指数前显示一个加号。 |
; |
子模式边界标记。子模式在 ; 之前时定义一个正值,在 ; 之后时定义一个负值。 |
/ |
JSF 扩展标记。如果存在,则加在最后一个子模式后面。请参阅下面的内容以了解其用法。 |
注意,不支持 ICU4J 符号 1-9(取舍)和 @(有效数字)。
模式包含一系列 0 和 # 符号来定义数中的最大数字数目。如果数字是一个前导零/结尾零,则被抑制并使用 # 符号来表示该数字。0 符号表示未被抑制的数字。在小数点左边,# 符号必须在任何 0 符号之前,在小数点右边,# 符号必须在任何 0 符号之后,例如,不允许 #0#。小数点符号标记(已本地化)小数点的显示位置。千位标记定义已本地化分组符号的显示位置,如果提供了分组字符,则小数点左边的第一“组”字符定义全局使用的分组模式。如果打开了 ICU4J,则最多可以使用两个千位标记而不是一个千位标记,其中一个用于标记主分组,一个用于标记辅助分组。在所有非印度语的语言中,如果提供了两个标记,则它们应具有相同的分组,例如,3 个数字,但在印度语中,它们可能指定不同的分组。指数标记表明此数字使用指数格式。如果提供了一对模式(使用子模式边界标记),则第一个模式定义一个正值,而第二个模式定义一个负值。如果数字使用指数格式,则 E 后面可能跟随一个加号或减号(仅有效位置),指示该指数在显示时始终带符号(加号或减号)。
例如,模式“###”表示数包含至多三个数字,其中前导零被抑制。模式 ##0.00 表示数包含至多三个数字、一个小数点以及两个小数数字,其中小数数字始终显示。模式 ###,###,##0.00 表示在小数点左边最多显示 9 个数字,且每隔 3 个十进制位显示一个分组(千位)分隔符。小数点左边始终显示至少一个数字(前导零被抑制),小数点右边始终显示两个数字。
可以将任何其他字符作为一个字面值前缀或一个后缀添加至模式。例如,$ ### 表示字面值字符“$ ”将显示在该数字的前面。在前缀/后缀中,下列字符具有特殊含义:
其中
' |
可以使用单引号将前缀或后缀中的特殊字符括起来,例如,“'#'#”将 123 格式化为“#123”。要生成单引号,请在一行中使用两个单引号:“# o''clock”。 |
% |
数字被处理为百分比(百分率),即,将数字乘以 100,并在此位置显示百分号。 |
‰ |
数字被处理为千分比(千分率),即,将数字乘以 1000,并在此位置显示千分号。 |
¤ |
此位置显示在语言环境信息中指定的货币符号。 |
注意,Java 对这些符号(除了引号)的显示作出了限制,规定它们只能在左前缀或右前缀中出现,但不能同时在左前缀和右前缀中出现。
可以采用两种方法对值进行填充。如果已打开 ICU4J,则可在前缀之前、前缀后一位置、后缀前一位置,或者在子模式末尾插入星号。星号后跟一个用于对值进行填充的字符。通过在标记的位置插入填充字符来将值填充至值的最大宽度。通过将正模式中前缀、后缀、数字字符、小数点和千位标记的宽度相加,可以计算出最大宽度。
换句话说,这些扩展用于使用提供的字符“填充”数字。例如,值 1 在应用 000/* 后,将显示为 **1。
API 调用 |
描述 |
---|---|
number = stringToValue(string) |
将字符串转换为 JavaScript 数字对象。失败时返回 NULL。 |
string = valueToString(number) |
将 JavaScript 数字转换为字符串。失败时返回 NULL。 |
string = lastError() |
如果转换失败,则将失败原因作为本地化字符串返回。 |
object = setAttribute(attribute) |
设置属性,或如果以前已设置属性,则更改其值。 |
string = getAttribute(attribute-name) |
检索属性的当前值。 |
将输入字段的值转换为 JavaScript 数字,然后给该数字加一并再次存储到结果。
// 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);
如上所述,考虑到阿拉伯-印度数字,应指定两个千位分组,并使用 ICU4J 填充方法在值中货币符号后面进行填充。
// 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:,.%‰-$"));