MyFaces Trinidad – using AJAX (PPR) for Row and Column Summaries in Tables

The built in Partial Page Rendering mechanism in Apache MyFaces Trinidad helps us implement AJAX-style features such as immediate calculation/derivation, validation, and conversion as well hide/display page element and refresh lists of values. Most of the PPR infrastructure can be used without any programming, in a completely declarative way. However, there are some exceptions, such as having non-MyFaces Trinidad components (JSF components from other libraries) initiate a PPR request or having such non-MyFaces Trinidad components refresh during a PPR request.

MyFaces Trinidad - using AJAX (PPR) for Row and Column Summaries in Tables 

Another situation where programmatic intervention is required is with the table component. Usually, a component is made to trigger refresh of other components by adding the id for that triggering component to the partialTriggers attribute of the dependent components. However, in a table, we do not know beforehand what the id values of the input elements will be: first of all we do not know the number of rows there will be and second of all, the id value is made unique by the JSF framework by adding :0, :1, :2 etc to elements in each row. In this case, using the partialTriggers attribute is not going to help us.

In the example we have a list of customers and for each customer the Date of Birth. Based on the Date of Birth, the Current Age is calculated within each row – for each customer, for example 97 for my grandmother. Additionally, we calculate the average age for all our customers. Currently that age is 46.

Now if the date of birth for one of the customers changed....

MyFaces Trinidad - using AJAX (PPR) for Row and Column Summaries in Tableswe want the calculated age for that customer as well as the average for all customers in the table to be automatically refreshed.

To trigger partial page rendering when a date of birth is changed, we need to set autoSubmit to true for the Date of Birth component:

  <tr:column sortProperty="dateOfBirth" sortable="true"
headerText="Date Of Birth" >
<tr:inputDate autoSubmit="true"
value="#{customer.dateOfBirth}"
valueChangeListener="#{CustomerManager.HandleDobChangeEvent}"/>
</tr:column>
 

Note that I have also added a valueChangeListener to the inputDate component. Now whenever the date of birth is changed, a PPR request is started and the server side JSF life cycle executed. As part of that life cycle, the setDateOfBirth method on the Customer bean is invoked and subsequently the CustomerManager’s HandleDobChangeEvent is invoked.

That valueChangeListener is implemented like this:

    public void HandleDobChangeEvent(ValueChangeEvent valueChangeEvent) {
UIComponent table =
((UIComponent)valueChangeEvent.getComponent()).findComponent("customers");
RequestContext.getCurrentInstance ().addPartialTarget(table);
}
 

It retrieves a handle to the table component – which has id="customers" – using the findComponent() method available on each UIComponent. Then, and here is the essence of this article, it adds this table component to the collection of partial targets in the current instance of the RequestContext, a Trinidad specific implementation of the FacesContext object.

The client side PPR processing JavaScript code will refresh in the client all components whose ID values are available in the list of partial targets. Therefore, whenever the Date Of Birth is changed and during PPR this valueChangeListener is invoked, the table component is added to the list of partialTargets and it gets refreshed – along with all its children – in the client. This means the new Age and AverageAge are shown:

MyFaces Trinidad - using AJAX (PPR) for Row and Column Summaries in Tables