Formatting money values with f:convertNumber - jsf

I had to customise a JSF XHTML template which has 2 different values and their sum displayed
<h:outputText value="#{Invoice.totalCharge/100 + Invoice.subscription/100}">
<f:convertNumber currencySymbol="£" groupingUsed="#{true}" maxFractionDigits="4" type="currency"></f:convertNumber>
</h:outputText>
<h:outputText value="#{Invoice.tax/100}">
<f:convertNumber currencySymbol="£" groupingUsed="#{true}" maxFractionDigits="4" type="currency"></f:convertNumber>
</h:outputText>
<h:outputText value="#{Invoice.grandTotal/100+Invoice.subscription/100}">
<f:convertNumber currencySymbol="£" groupingUsed="#{true}" maxFractionDigits="4" type="currency"></f:convertNumber>
</h:outputText>
With values displayed as
720.1252 +
144.025 =
864.1502
I set maxFractionDigits to 4 deliberately to confirm my suspicions. It has to be 2 in the end but in that case and thats where the problem is
With fraction digits = 2 you get
720.13 +
144.03 =
864.15
Which for a person looking at the printout is plain crap.
When and how should I do the math so that the result makes sense to the bean counters across the office and not techies like us?
I have no access to the source all I can change is this XHTML template.

Related

How to round values in JSF?

Please help me to round values (example: from 4.23 to 4 and 4.5 to 5). I have code such as below. I need do this on my frontend part:
<p:column
styleClass="#{SomeClass.getAnotherSomething(row.magicCategory)}">
<h:outputLabel value="#{empty row.papaja ? 'N/A' : row.papaja}"
styleClass="textChangesInCells"
pt:data-selenium="papaja" />
</p:column>
You need to use h:outputText instead of h:outputLabel. With h:outputText you can use f:convertNumber to format a numeric value. With format="0" it'll round the value. So:
<h:outputText value="#{row.papaja}">
<f:convertNumber pattern="0"/>
</h:outputText>
To handle 'N/A', you need to do a check using c:if, c:choose, or use rendered attributes.

Column header not visible when column is conditionally rendered

I have a h:dataTable. I would like to render a row conditionally as follows:
<h:dataTable value="#{myController.entities}" var="entity">
<h:column rendered="#{entity.selected}">
<f:facet name="header">
<h:outputText value="header" />
</f:facet>
<h:outputText value="#{entity.name}" />
</h:column>
</h:dataTable>
In my controller there is variable List <Entity> entities which has getters and setters.
Entity class contains two variables : boolean selected and String name with its getters and setters.
When #{entity.selected} is false, then the row is hidden. When #{entity.selected} is true, then the row is shown, but without header. When I do not use the rendered attribute on the column my header becomes visible.
This question is similar to p:column header facet is not shown when rendered attribute is used on p:column
But none of the solution given works for me and Iam not using primefaces.
Can somebody help me with this? Iam new to JSF and the mistake might be something silly and fix fairly easy, but please help me figure it out. Thanks.
Iam posting the outputs that I get when I tried the above code.
**Header**
name 0
name 1
name 2
name 3
name 4
This output shows the datatable using simply <h:column> without trying to render it conditionally. The header can be seen.
Now when I use conditional rendering:
name 1
name 3
In this output Iam trying to use conditional rendering <h:column rendered="#{entity.selected}">. As you can see that for "name 0", "name 3" and "name 5" the #{entity.selected} is false and hence its not rendering.
This is exactly what I need but only if the header shows up.
I want to render my row invisible where the #{entity.selected} value is false. Also show the column header. Can this be possible?
You need to put the rendered condition on the cell, not on the column.
<h:dataTable value="#{myController.entities}" var="entity">
<h:column>
<f:facet name="header">
<h:outputText value="header" />
</f:facet>
<h:outputText value="#{entity.name}" rendered="#{entity.selected}" />
</h:column>
</h:dataTable>
Or, if you've multiple components or plain text representing cell content, wrap it in a <h:panelGroup> or <ui:fragment>.
<h:dataTable value="#{myController.entities}" var="entity">
<h:column>
<f:facet name="header">
header
</f:facet>
<h:panelGroup rendered="#{entity.selected}">
Blah blah #{entity.name} blah blah
</h:panelGroup>
</h:column>
</h:dataTable>
(note: you don't necessarily need h:outputText over all place, see also Is it suggested to use h:outputText for everything?)
Apply if necessary the following CSS on the table to hide empty cells in case you've applied e.g. borders or bgcolors on table cells:
table {
empty-cells: hide;
}
A completely different alternative is to provide a new model which contains only the desired entities:
<h:dataTable value="#{myController.selectedEntities}" var="entity">
<h:column>
<f:facet name="header">
header
</f:facet>
#{entity.name}
</h:column>
</h:dataTable>
Instead of
...
<f:facet name="header">
<h:outputText value="header" />
</f:facet>
...
try simply
...
<f:facet name="header">Header</f:facet>
...

Display formatted decimal numbers in Primefaces 4 [duplicate]

This question already has an answer here:
Displaying a number in 2 point decimal format in jsf
(1 answer)
Closed 5 years ago.
I have a database table with a float field and I want to display it through Primefaces.
I want to display the numbers formatted as (one thousand, for example): 1.000,00
I tried:
<p:column sortBy="#{item.value}" filterBy="#{item.value}">
<f:facet name="header">
<h:outputText value="#{epoBundle.ListUpbTitle_value}"/>
</f:facet>
<h:outputText value="#{item.value}"/>
<f:convertNumber pattern="#0.000" locale="pt_BR"/>
</p:column>
But got:
/WEB-INF/include/entity/upb/List.xhtml #80,55 Parent not an instance of ValueHolder: org.primefaces.component.column.Column#13ec99d0
Can someone help me?
Thanks in advance.
f:convertNumber must be inside h:outputText.
<h:outputText value="#{item.value}">
<f:convertNumber pattern="#0.000" locale="pt_BR"/>
</h:outputText>

Masking numbers in PrimeFaces datatable

Related to the question Display formatted decimal numbers in Primefaces 4, how can I display - in a PrimeFaces datatable - a number masked like this:
1.987.654,32
The original data, which are read from a float column in SQLServer database table, is (e.g.):
1987654.32
I've tried the code below, but no success:
<p:column sortBy="#{item.value}" filterBy="#{item.value}">
<f:facet name="header">
<h:outputText value="#{epoBundle.ListUpbTitle_value}"/>
</f:facet>
<h:outputText value="#{item.value}">
<f:convertNumber pattern="#0.000" locale="pt_BR"/>
</h:outputText>
</p:column>
Thanks in advance.
The correct pattern for the <f:convertNumber .../> you want is: ###,###.000. You can read more about decimal formatting here: http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
Bonus: for different masks, you can use other locales: https://stackoverflow.com/a/11836387/1362049

rich:dataTable getting the total from filterBy columns

I have a rich datatable with columns that I can filter.
<!-- Data table with filters -->
<h:form>
<rich:dataTable value="#{sessionScope.paymentsBean.payments}" var="payment"
id="table">
<rich:column filterBy="#{sessionScope.payment.invoice}" filterEvent="onkeyup">
<f:facet name="header">Invoice</f:facet>
<h:outputText value="#{sessionScope.payment.invoice}" />
</rich:column>
<rich:column filterBy="#{sessionScope.payment.description}" filterEvent="onkeyup">
<f:facet name="header">Description</f:facet>
<h:outputText value="#{sessionScope.payment.description}" />
</rich:column>
<rich:column filterBy="#{sessionScope.payment.amount}" filterEvent="onkeyup">
<f:facet name="header">Amount</f:facet>
<h:outputText value="#{sessionScope.payment.amount}" />
</rich:column>
</rich:dataTable>
</h:form>
<!-- Total -->
<h:outputText id="total" value="#{sessionScope.paymentsBean.total}" >
<f:convertNumber maxFractionDigits="2" type="currency" currencySymbol="$"/>
</h:outputText>
For the total, I can sum all the amounts in sessionScope.paymentsBean.payments to get the total. Which is $355.00 in the following example.
Invoice Description Amount
1 Cash $5.00
2 Visa $50.00
3 Visa $100.00
4 MasterCard $200.00
Total: $355.00
However, if I filter by "Visa", the table and total would look like:
Invoice Description Amount
2 Visa $50.00
3 Visa $100.00
Total: $355.00
The total should be $150 but getTotal() doesn't know about the filterBy data.
Is there a way to dynamically calculate the total based on the filterBy criteria from the rich:datatable?
There's a way to recover the filtered data. You need the table to be binded to a backing bean property and you need it to be a rich:extendedDataTable.
<rich:extendedDataTable value="#{sessionScope.paymentsBean.payments}" var="payment"
id="table" binding="sessionScope.paymentsBean.table">
Binded attribute will be HTMLExtendedDataTable type. After that you will need to create an Ajax call when user types something in the filter, to be called. See <a4j:support /> component and use it when a key is pressed, as:
<a4j:support event="onkeyup" reRender="countBox" action="#{sessionScope.paymentsBean.actionCalculateTotalValue}"/>
Remember calling Ajax method on filterings can be tricky. I sincerely suggest to avoid the table's built-in filters and create your custom ones based in h:inputText and implement your ajax calls here. You can take a look into this link.
Once the method is called you just need to obtain the filtered rows, calculate the total amount and put in in a variable, over which JSF will update the box when the call is finished. What's the way to get the filtered rows? There you have:
public List<E> filteredList() {
List<E> list = new java.util.ArrayList<E>();
int i = 0;
boolean loop = true;
while (loop) {
table.setRowKey(new Integer(i));
if (table.isRowAvailable()) {
list.add((E) table.getRowData());
i += 1;
} else {
loop = false;
}
}
table.setRowKey(null);
return list;
}
Basically it makes a loop until there are no more available rows in the table. Good luck.

Resources