1

Hi in my project I need to visualize currency value, as far in my f:convertNumber

I use a fixed currencySymbol; everything is ok, but when I try to get the symbol with an expression language like this:

<h:outputText value="#{rowItem.value}">
    <f:convertNumber currencySymbol="#{rowItem.getCurrencySymbol()}" groupingUsed="true" maxFractionDigits="2" type="currency" />
</h:outputText>

it is like the method getCurrencySymbol is not called, I am sure there is something I am missing.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
arpho
  • 1,576
  • 10
  • 37
  • 57

1 Answers1

6

That will happen if #{rowItem} is only available during view render time, such as when it's specified by <h:dataTable var="rowItem">, as the variable name itself already suggests. It can also happen if #{rowItem} gets changed between building the view and rendering the view, such as when it's coming from a dropdown component in the same form. The <f:convertNumber> is namely a taghandler, not an UI component. It gets executed during view build time, not during view render time. The desired #{rowItem} value is not per definition available during view build time.

This all is explained in JSTL in JSF2 Facelets... makes sense? In that answer, you can substitute "JSTL" with <f:convertNumber> as they both are taghandlers and thus have exactly the same lifecycle.

There's no solution in standard JSF API without creating a custom converter and changing the view or model. You can find possible solutions in this answer: How to set converter properties for each row/item of h:dataTable/ui:repeat?

The JSF utility library OmniFaces offers <o:converter> out the box for exactly this problem. Use it as follows:

<h:outputText value="#{rowItem.value}">
    <o:converter converterId="javax.faces.Number" currencySymbol="#{rowItem.getCurrencySymbol()}" type="currency" />
</h:outputText>

(note that I omitted the other two properties as those are the default already when type="currency" is used)

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555