p:datatable summary row calculation

匿名 (未验证) 提交于 2019-12-03 00:56:02

问题:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!