Displaying table with fields from different object and fast columns sorting
It is not uncommon to stumble across some problems when you want to display a table containing fields from various different objects.
In order to do that properly, you should make use of Wrapper Class.
Wrapper Class
Wrapper Class usually takes the form of an inner class inside the controller and combines all the data retrieved from the database.
Having a table with fields from only one object seems way easier, than putting multiple objects inside.
And quite frankly it is.
Sorting
With that settled, we can now move on to sorting.
First of all, we need our wrapper class to implement a Comparable interface. The interface is only natural to use in order to compare two custom objects with each other, based on different criteria.
An example of such wrapper class would look like this:
public class OrdersB2BPageObject implements Comparable {
public String orderNumber {
get;
set;
}
public String reference {
get;
set;
}
public OrdersB2BPageObject(String orderNumber, String reference) {
this.orderNumber = orderNumber;
this.reference = reference;
}
public Integer compareTo(Object compare) {
OrdersB2BPageObject compareTo = (OrdersB2BPageObject) compare;
if (OrdersB2BPageController.sortBy.equals('OrderNumber')) {
return -orderNumber.compareTo(compareTo.orderNumber);
} else if (OrdersB2BPageController.sortBy.equals('Reference')) {
if (reference == null && compareTo.reference != null) {
return -1;
} else if (reference != null && compareTo.reference == null) {
return 1;
} else if (reference == null && compareTo.reference == null) {
return 0;
}
return reference.compareTo(compareTo.reference);
}
return null;
}
In this case, orderNumber is a field from Order object and reference can be a field from any other object.
Having the comparator for all of the fields, we need to use it in order to sort columns.
For that purpose, our controller will hold the attribute “sortBy” which will hold the information about which column was clicked in order to be sorted.
You may notice that this variable is used in the “compareTo” method inside the wrapper class.
We also need a method that is fired after the column click, which looks like that:
public PageReference sortColumn() {
ordersB2BPageObjects.sort();
orderListIterable = new OrderB2BListIterable(ordersB2BPageObjects);
next();
return null;
}
And finally let us move on to the Visualforce page:
<apex:page controller="OrdersB2BPageController">
<apex:pageBlock id="ThePage">
<apex:form >
<apex:pageBlockTable value="{!listController}" var="orderB2B">
<apex:column >
<apex:facet name="header">
<apex:commandLink value="{!$Label.Community_orderNumber}" action="{!sortColumn}" reRender="ThePage">
<apex:param name="compareField" value="OrderNumber" assignTo="{!sortBy}"/>
</apex:commandLink>
</apex:facet>
<apex:commandLink value="{!orderB2B.orderNumber}" action="{!getSelectedOrder}" reRender="OrderItems">
<apex:param name="orderNumber" value="{!orderB2B.orderNumber}"
assignTo="{!selectedOrderNumber}"/>
</apex:commandLink>
</apex:column>
<apex:column value="{!orderB2B.reference}">
<apex:facet name="header">
<apex:commandLink value="{!$Label.Community_reference}" action="{!sortColumn}" reRender="ThePage">
<apex:param name="compareField" value="Reference" assignTo="{!sortBy}"/>
</apex:commandLink>
</apex:facet>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
And just as a brief explanation:
the main part for our sorting is everything inside the apex:facet markup.
We create an apex:commandLink out of the columns header which fires !sortColumn action and Rerenders whole page after that.
Additionally to the click, using apex:param we assign the value of the corresponding column to the “sortBy” attribute from the controller.
I hope this will clarify all the uncertainties and will help you out in your work!