function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
m_roarkm_roark 

Is there a way to control sort order for an 'apex: datatable'?

The subject basically says it all.  Is there a way to do this?  I need to display the elements in my table in a specific sort order.
TehNrdTehNrd
A great post on sorting:

http://blog.sforce.com/sforce/2008/09/sorting-collect.html
m_roarkm_roark
Hi, and thanks for the quick response.  However, I should have specified. 

I need a way to do this natively, without calling APEX classes.  The page I need to use this on is in a VisualForce email template, and I cannot call custom extensions.  Is there an attribute or element I can include in my datatable construction which will automatically sort by a specific element of data the list of related data elements in the 'value' attribute and display them in this sorted order?

My use case is an autogenerated Invoice, where I need to display the list of specific products sorted by product name.
TehNrdTehNrd
I think you could build a custom component which can use a custom controller and then you can put this component in the email template.
m_roarkm_roark
Originally I used a custom component in the email template, but I encountered an error which told me the component did not have 'global' security access.  I had to remove the component in order to save the template.

I will take a further look into this, and see if this will help.  Thanks for the suggestion.
jwetzlerjwetzler
Then you need to set access="global" on your component.
TehNrdTehNrd
I hadn't actually built a component yet and I figured this was a good place to start. Here is what I did:

Code:
Component:

<apex:component access="global" controller="orderedLineItems">
<apex:attribute name="opportunityID" description="This is the ID of the oppotunity." type="ID" assignTo="{!opportunityID}" />
<!--I suppose you could send over a list of lineItems but this would only really work well with a StandardController as you can pass related Lists but to make
this work in pages that use custom controllers I am only passing the Opp Id and then I will query for the products -->
<!--<apex:attribute name="opportunityLineItems" description="List of the OpportunityLineItems." type="OpportunityLineItem[]" />-->

<apex:dataTable value="{!lineItems}" var="l">
<apex:column value="{!l.pricebookEntry.Name}"/>
<apex:column value="{!l.Quantity}"/>
<apex:column value="{!l.UnitPrice}"/>
<apex:column value="{!l.TotalPrice}"/>
</apex:dataTable>
</apex:component>


Controller:

public class orderedLineItems {

public Id opportunityID {get; set;}
List<OpportunityLineItem> lineItems;

public List<OpportunityLineItem> getlineItems(){
if(lineItems == null){
/*Using dyanamic apex and SOQL you could set this up to query all*/
lineItems = [select Id, PricebookEntry.Name, Quantity, UnitPrice, TotalPrice from OpportunityLineItem where OpportunityID =:opportunityID]; lineItems = sortLines(lineItems); } return lineItems; } private static List<OpportunityLineItem> sortLines(List<OpportunityLineItem> olis) { List<OpportunityLineItem> resultList = new List<OpportunityLineItem>(); /* Create a map of amount to Opportunity collection */ Map<String, List<OpportunityLineItem>> oliMap = new Map<String, List<OpportunityLineItem>>(); for(OpportunityLineItem oli : olis) { if(oliMap.get(oli.PricebookEntry.Name) == null){ oliMap.put(oli.PricebookEntry.Name, new List<OpportunityLineItem >()); } oliMap.get(oli.PricebookEntry.Name).add(oli); } List<String> keys = new List<String>(oliMap.keySet()); /* Leverage the standard, primitive collection sort method */ keys.sort(); for(String key:keys){ resultList.addAll(oliMap.get(key)); } return resultList; } }

VF Email template:

<messaging:emailTemplate subject="Testing" recipientType="Contact" relatedToType="Opportunity">
<messaging:htmlEmailBody >
This is your new Visualforce Email Template.<br/>

<c:orderedLineItems opportunityID="{!relatedTo.ID}"/>

</messaging:htmlEmailBody>
</messaging:emailTemplate>


You could get even fancier with the component and add addtional attributes such as sortDirection, fieldToSort, etc.

Hope that helps.
-Jason



Message Edited by TehNrd on 12-05-2008 09:49 AM
m_roarkm_roark
That worked for my needs!  Thank you all for your contributions!
MATTYBMEMATTYBME
How could the code, descibed, be used to sort Case Date/Time Opened in descending order? I am sorry but I just can't seem to understand the complexity of sort()
OcoBriOcoBri
Has this feature been added yet?