-
Bug
-
Resolution: Fixed
-
Normal
-
Freshly, 8.6.4, 9.5.0, 9.1.0
-
Security Level: Jimmy
-
ZK 9.5.1 S1
Steps to Reproduce
run the attached test case DecimalboxWithLocaleFormatTest.java
or this zul snippet:
<zk> <decimalbox id="decimalbox" value="300000" format="locale:en-US" constraint="no negative: it shall not be negative"/> <separator/> <button label="getValue() triggers WrongValueException" onClick="Clients.log(decimalbox.getValue());"/> </zk>
Current Result
When calling getValue a WrongValueException is thrown even with a valid positive value
Only positive number or zero is allowed org.zkoss.zk.ui.WrongValueException: Only positive number or zero is allowed at org.zkoss.zul.SimpleConstraint.wrongValue(SimpleConstraint.java:409) at org.zkoss.zul.SimpleConstraint.validate(SimpleConstraint.java:367) at org.zkoss.zul.impl.InputElement.validate(InputElement.java:359) at org.zkoss.zul.impl.InputElement.setText(InputElement.java:310) at org.zkoss.zul.impl.InputElement.checkUserError(InputElement.java:724) at org.zkoss.zul.impl.InputElement.getTargetValue(InputElement.java:547) at org.zkoss.zul.Decimalbox.getValue(Decimalbox.java:59) at DecimalboxWithLocaleFormatTest.testEnUS(DecimalboxWithLocaleFormatTest.java:27) DecimalboxWithLocaleFormatTest > testEnUS FAILED org.zkoss.zk.ui.WrongValueException at DecimalboxWithLocaleFormatTest.java:27 2 tests completed, 1 failed
Expected Result
no exception, correct locale/constraint validation
Debug Information
Using a specific locale ("xx-YY") in combination with a "no negative" constraint, the "-" in the locale is interpreted as a MINUS negating the value when formatting the number during the input validation.
happens in line 228: (the locale:xx-YY is literally prepended to the number):
https://github.com/zkoss/zk/blob/v9.1.0/zul/src/org/zkoss/zul/impl/NumberInputElement.java#L228
Workaround
override the formatNumber method to consider "locale:xx-YY" format strings:
public class DecimalboxPatched extends org.zkoss.zul.Decimalbox { @Override protected String formatNumber(Object value, String defaultFormat) { if (value == null) return ""; String fmt = getFormat(); if (fmt == null) { fmt = defaultFormat; } boolean isLocaleFormat = fmt.startsWith("locale:"); final Locale loc = isLocaleFormat ? Locale.forLanguageTag(fmt.substring(7)) : getDefaultLocale(); final DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(loc); int roundingMode = getRoundingMode(); if (roundingMode != BigDecimal.ROUND_HALF_EVEN) df.setRoundingMode(RoundingMode.valueOf(roundingMode)); if (fmt != null && !isLocaleFormat) { try { df.applyPattern(fmt); } catch (IllegalArgumentException e) { if (getLocale() != null) df.applyLocalizedPattern(fmt); } } return df.format(value); } }
- relates to
-
ZK-3704 Decimalbox supports Indian numbering system format
- Closed