可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a p:dataTable
pretty similar to the showcase. Unfortunatly, the showcase uses randomly generated values for the p:summaryRow
.
Refering to the showcase, imagine the car had a price attribute.
How would I sum up the price for the cars grouped by the specified column for displaying it in the summary row?
回答1:
I have same problem with you and found correct usage from primefaces blog SummaryRow from primefaces forum
this is some example show correct calculation for sum price, count...
Listener gets the group property which is the sortBy value which you can use to calculate totals or any other operation.
<p:summaryRow listener="#{backingBean.calculateTotal}"> <p:column colspan="3" style="text-align:right"> Total: </p:column> <p:column> #{backingBean.total} </p:column> </p:summaryRow> /* listener method in your bean */ public void calculateTotal(Object o) { this.total = 0.0d; String name = ""; if(o != null) { if(o instanceof String) { name = (String) o; for(MyRowObject p : (List<MyRowObject>) dataTableModel.getWrappedData()) { // The loop should find the sortBy value rows in all dataTable data. switch(sortColumnCase) { // sortColumnCase was set in the onSort event case 0: if(p.getcolumn0data().getName().equals(name)) { this.total += p.getcolumn0data().getValue(); } break; case 1: if(p.getcolumn1data().getName().equals(name)) { this.total += p.getcolumn1data().getValue(); } break; } } } } }
回答2:
this is my solution:
<p:dataTable var="elem" value="#{unitSubStatusChart.resultList}" tableStyleClass="app-table-auto"> <et:defaultPaginator /> <p:column headerText="#{bundle['class']}" sortBy="#{elem.dtype}"> <e:outputIconText icon="#{icons[elem.dtype]}" value="#{bundle[elem.dtype]}" /> </p:column> <p:column headerText="#{bundle['status']}" sortBy="#{elem.status}"> <h:outputText value="#{bundle[elem.status]}" /> </p:column> <p:column headerText="#{bundle['subStatus']}" sortBy="#{elem.subStatus}"> <h:outputText value="#{bundle[elem.subStatus]}" /> </p:column> <p:column headerText="#{bundle['count']}"> <h:outputText value="#{elem.count}" /> </p:column> <p:summaryRow listener="#{unitSubStatusChart.onSummaryRow}"> <p:column colspan="3" style="text-align:right"> <h:outputText value="#{bundle.total}:" /> </p:column> <p:column> <!-- !!! NOTE THIS VALUE EXPRESSION !!! --> <h:outputText value="#{component.parent.attributes.total}" /> </p:column> </p:summaryRow> </p:dataTable>
and this is the listener:
public void onSummaryRow(Object filter) { FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ELResolver elResolver = elContext.getELResolver(); DataTable table = (DataTable) UIComponent.getCurrentComponent(facesContext); UIColumn sortColumn = table.getSortColumn(); ValueExpression expression = sortColumn.getValueExpression("sortBy"); ValueReference reference = ValueExpressionAnalyzer.getReference(expression); String property = (String) reference.getProperty(); int total = 0; List<?> rowList = (List<?>) table.getValue(); for(Object row : rowList) { Object value = elResolver.getValue(elContext, row, property); if(filter.equals(value)) { // THIS IS THE ONLY POINT TO CUSTOMIZE total += ((UnitResult) row).getCount(); } } List<UIComponent> children = table.getSummaryRow().getChildren(); UIComponent column = children.get(children.size() - 1); column.getAttributes().put("total", total); }
This listener has no external references: it does not depend on previous onSort events/listeners and it doesn't need any field in the bean.
回答3:
I will suggest a possible way to do this, may not be the most perfect, but i believe it will help.
Ther's the steps:
1 - Declare a class atribute to acumulate the total group value:
... @Named(value = "myBean") @YourScope public class InscricaoBean implements Serializable { ... //in this example i will use a int type private int acumulatorAux = 0; ...
2 - Create a function to return the total value per group:
... public int getAcumulatedValue() { int aux = acumulatorAux ; acumulatorAux = 0; return aux; } ...
3 - Create an method to acumulate values per group:
... public void acumulateValue(int value) { acumulatorAux += value; } ...
4 - On JSF page, you need to call acumulateValue
method for every row, something like:
... <p:dataTable value="#{myBean.getList()}" var="testVar"> <p:column headerText="Header" sortBy="#{testVar.name}"> #{inscricaoBean.acumulateValue(testVar.value)} <h:outputText value="#{testVar.name}" /> </p:column> ...
5 - And next, you can have a summaryRow
like:
... <p:summaryRow> <p:column colspan="1" style="text-align:right"> <h:outputText value="Total:" /> </p:column> <p:column> <h:outputText value="#{inscricaoBean.getAcumulatedValue()}" /> </p:column> </p:summaryRow> ...
Well, this is a gross way to acomplish this task. I think you can improve, but it was the first think when i see your question.
Hope it helps.