Search code examples
jsfcurrencynumber-formatting

<f:convertNumber/> does not recognize correct input for german currency


I'm setting up an input field for currency in my jsf web app and have a backing bean to write the value to. However the converter <f:convertNumber/> doesn't seem to recognize correct input if entered by the user. The initial value can be submitted and numbers can be changed but typing in a value like 1,00 € won't work. I would like to keep the formatter and also understand how to fix this problem.

I am using JSF 2.3.5-SP2 (Mojarra) with Wildfly 14.0.1 and Java 10.0.1

I narrowed it down to the space between the number and the currency symbol but I don't know how to make <f:convertNumber/> recognize a simple space as a correct input.

After doing a little inspection the original space was identified as a non-breaking space &nbsp;

This is my test code:

test.xhtml

<h:body>
    <h:form>
        <h:inputText value="#{testModel.number}">
            <f:convertNumber type="currency" locale="de_DE" currencyCode="EUR"/>
        </h:inputText>
        <h:commandButton value="Submit" action="#{testModel.submit}"/>
        <h:messages style = "color:red;margin:8px;" />
    </h:form>
    <h:outputText value="#{testModel.number}"/>
</h:body>

TestModel.java

@Named
@RequestScoped
public class TestModel {
    private BigDecimal number;

    public String submit(){
        return "#";
    }

    public BigDecimal getNumber() {
        if(number==null)number = new BigDecimal("0");
        return number;
    }

    public void setNumber(BigDecimal number) {
        this.number = number;
    }
}

When changing the number to 1,00 € by only ereasing the 0 of 0,00 € and replacing it with a 1 I get the correct output.
image of correct output

When I replace the &nbsp;(non-breaking) space between the number and the '€' symbol with a simple space the messsage shows the following warning:

j_idt3:j_idt4: '0,00 €' konnte nicht als Währungswert interpretiert werden.
meaning '0,00 €' couldn't be interpreted as a currency value.
image of wrong recognition


Solution

  • I tried to reproduce this using your exact code and was unable to. In fact, any #,## € input seems to be working just fine. Please note that f:convertNumber uses DecimalFormat under the hood - so there might be slight changes not only between JSF versions but potentially also between different versions of Java.

    I ran your code with JSF 2.3 and Java 8 and it's parsing the string fine even with a space between the number and the Euro sign. Maybe you are triggering a localization bug that has been fixed in a later version ?

    Update

    It seems on my specific version of Java (Java 8, 191-b12), JSF implementation (2.3.3.99, Mojarra) and localization rules the behavior is the exact opposite. If I pass a &nbsp; in the inputText the converter will refuse to parse it. Maybe this is indeed a clash between localization rules and the behavior of the component. I had to force this character into the inputText to trigger it though, as the browser will insert simple spaces by default.

    Working around the problem

    Lucklily after some testing I discovered you can actually work around the problem by supplying a pattern attribute. In your specific case, the solution would be to do something like this,

    <f:convertNumber pattern="#,##0.00 ¤" type="currency" locale="de_DE" currencyCode="EUR"/>
    

    This will expect a pattern where the space between the Euro sign and the number is a simple space (&#32) character, instead of a &nbsp; which seems to be the default behavior in your environment for some reason.