rich:dataTable getting the total from filterBy columns - jsf

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.

Related

Datatable with dynamic columns, multiple colums per object

I have dynamic number of Tests (measurements) for each item (Apple, Banana) and every Test has 2 Properties (mandatory, visible). What I need is table that shows these Tests as columns (colspan=2) and its Properties (colspan=1), like in example below. I can do it for table header (using Primefaces' p:columnGroup) but I don't know how to fill two columns for every Property while iterating through properties list.
Only idea I have is to make new List where every item will exist twice (Diameter, Diameter, Length, Length), iterate over it and use some modulo condition to choose correct property.
My current solution is:
xhtml
<p:dataTable var="scenario">
...
<p:columns var="property" value="#{view.getXTimesProperties()}"
columnIndexVar="index">
<c:set var="test" value="#{view.getTest(scenario, property)}"/>
<c:choose>
<c:when test="${index % 2 == 0}">
<h:outputText value="#{test.mandatory}"/>
</c:when>
<c:when test="${index % 2 == 1}">
<h:outputText value="#{test.visible}"/>
</c:when>
</c:choose>
</p:columns>
</p:dataTable>
and View method is
public List<Property> getXTimesProperties() {
List<Property> list = new ArrayList<>(properties.size() * 2);
for (Property property : properties) {
list.add(property);
list.add(property);
}
return list;
}
Is there a better way? Thanks in advance for better idea!
Yes, better way (credits to Kukeltje):
<p:dataTable var="scenario">
...
<c:forEach var="property" items="#{view.properties}">
<c:set var="test" value="#{view.getTest(scenario, property)}"/>
<p:column>
<h:outputText value="#{test.mandatory}"/>
</p:column>
<p:column>
<h:outputText value="#{test.visible}"/>
</p:column>
</c:forEach>
</p:dataTable>

Primefaces datatable Identify if the current column is of date type

I am trying to make a common datatable using primefaces.
I want to check if the current column of datatable is of Date type. If it is a Date I want to add DatetimeConverter -
Here is my code -
<ui:component>
<p:dataTable id="#{tableId}" value="#{data}" var="row" styleClass="stdTable vertLines fndTable vertLinesRightBorder"
style="table-layout:fixed; border-color: #dddddd;">
<p:columns value="#{tableColumns}" var="column" sortBy="#{row[column.property]}">
<f:facet name="header">
#{column.header}
</f:facet>
#{row[column.property]}
</p:columns>
</p:dataTable>
</ui:component>
I am calling the above xhtml as follows-
<ui:include src="table.xhtml">
<mbcpos:param name="tableId" value="#{me.id}hTabel1" />
<mbcpos:param name="data" value="#{taskListBean.receivedOwnerTasks}" />
<mbcpos:param name="tableColumns"
value="#{me.columns}" />
</ui:include>
Can we identify the column datatype :
e.g., #{row[column.property]} equals Date
If the column is a date I want to format the date.
Your column model should be where you put the data type it holds and other data type presentation related things like masks, currency, alignment etc.
On the page, for each data type (according to your needs), inside the p:columns
you should do something like this:
<h:outputText rendered="#{column.dateType}" value="#{row[column.property]}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>

jsf tabledata dynamic inputtext

I have a List in my backing bean. I want to present it in a table. I want table to have two rows - on left side, values from the list, and on the right side inputBoxes. It's the easy part. Here's my code:
<div class="table">
<h:dataTable id="korekty" styleClass="table table-hover"
value="#{searchBean.listX}" var="v">
<h:column>
<f:facet name="header">XXX</f:facet>
#{v.string}
</h:column>
<h:column>
<f:facet name="header">YYY</f:facet>
<h:inputText styleClass="form-control">
</h:inputText>
</h:column>
</h:dataTable>
</div>
The hard part of my problem is : in those inputtext user might put some numbers. Then after hitting SUBMIT button I want to create a list/map/whatever of inputed values. How can I do that? Thanks for help
First of all, prepare an array, or a list, containing placeholders for the given data alongside the list you've got:
List<String> initialData = ...;//initial data of n size
String[] submittedData = new String[initialData.size()];//array of the same size
Then, bind the <h:dataTable> component to the view to get access to the current row index of the iteration. This way you can finish your job by binding value of input elements to the corresponding objects in the array/list:
<h:dataTable binding="#{table}" ... >
<h:column>
<f:facet name="header">YYY</f:facet>
<h:inputText value="#{searchBean.submittedData[table.rowIndex]}" ... />
</h:column>
</h:dataTable>

Jsf - dataTable data doesn't refresh on the client side

I have an ice:dataTable like this.
<ice:dataTable id="pdet"
value="#{outerBean.nestedClassList}"
var="nestedObject" rendered="true">
<ice:column>
<f:facet name="header">Order Number</f:facet>
<ice:outputText value="#{nestedObject.orderNumber}" />
</ice:column>
<ice:column>
<f:facet name="header">Qty</f:facet>
<ice:inputText value="#{nestedObject.qty}"
id="qty"
label="'Qty' FOR 'Order Number':#{nestedObject.orderNumber} "
partialSubmit="true"
valueChangeListener="#{nestedObject.qtyChanged}"
validator="#{nestedObject.validateQty}">
</ice:inputText>
</ice:column>
</ice:dataTable>
There is a drop down list, depend on the selected value, I want to populate the particular data set. Always there is a value for qty and that should be allowed to change the value. For an instance, without changing that qty ice:inputText, if I change the selected value from the drop down list, a new data set will populate, but from the client side, it shows the previous values for the qty. But bean keeps the real value. If I use a ice:outputText for the qty field, then it shows the exact value. How do I prevent this? What I'm missing?
Thanks.

Value of <h:selectBooleanCheckbox> inside <p:dataTable> remains false on submit

I have a primefaces datatable and inside the primefaces datatable, I have a column, which contains the . The issue is,I have set the default value for the as false. When I click/check the , its still retrieving the value as false. I tried it multiple times but not sure why its returning false. Please find the sample code below.
<p:dataTable id="review-table" var="item" value="#{demandBean.filterVOList}">
<p:column id="SelectallID" style="text-align: left; width:40px;" rendered="#{demandBean.screeRenderVo.selectAllRenderer}">
<f:facet name="header" >
<h:outputText id="selectId" value="#{demandBean.dmdScreenLabelVO.selectAll}" />
<div></div>
<h:selectBooleanCheckbox id="checkbox1" value="Select All" onclick="checkAll(this)"/>
</f:facet>
<h:selectBooleanCheckbox id="checkbox2" value="#{item.selected}"/>
</p:column>
Im getting the value as false, when I check the and click on the save button. I have written an Action listerner, below is the code corresponding to the actionListener
public void saveData(ActionEvent event)
{
System.out.println("Entering the Save :");
selected = isSelected();
System.out.println("value of Selected"+selected);
}
I have tried debugging the code as well, but not sure why the value for is getting displayed as false. Please Assist. Thanks in Advance
You seem to be binding the value of all checkboxes in the column to the one and same bean property. This way the value will ultimately end up to be the one of the last row in the column.
This is not how it's supposed to be used.
You basically need to bind the value of the checkbox to the property of the currently iterated row object (the one behind the var attribute of the datatable).
<p:dataTable value="#{bean.items}" var="item">
<p:column>
<p:selectBooleanCheckbox value="#{item.selected}" />
Alternatively, you could use the <p:column selectionMode="multiple" /> to use builtin multiple selection support of the PrimeFaces datatable (see also the showcase example).
<p:dataTable value="#{bean.items}" var="item" rowKey="#{item.id}" selection="#{bean.selectedItems}">
<p:column selectionMode="multiple" />

Resources