Custom sorting of a collection in Apex

Apex will allow you to make an order List of objects that you can then iterate over and manipulate. However, Apex will not let you use the built-in sort method for List to sort sObjects by a field inside. To do this, we have to implement our own comparable class to do the sorting for us.

To implement the Comparable interface, you must first declare a class with the implements keyword as follows

global class Employee implements Comparable {}

Next, your class must provide an implementation for the following method:

global Integer compareTo(Object compareTo) {}

Note: The implemented method must be declared as global or public.

The implementation of this method should return the following values:

  • The current value is greater than the compared value: return 1
  • The current value is equal to the compared value: return 0
  • The current value is less than the compared value: return -1

If we want to develop different type of sorting like column sorting, multilevel sorting on collection to show the collection on visualforce page.

e.g.

Visualforce page:

<apex:page controller="compare1_sorting">
    
    <apex:form >
        
        <style type="text/css">
            th{text-align:center;}
            
            .button {
            
            }
            .customPopup {
            background-color: white;
            border-style: solid;
            border-width: 1px;
            padding: 25px;
            padding-bottom:35px;
            width: 500px;
            margin-left: 200px;
            margin-top: -100px;
            position:fixed;
            top:49%;
            }
            
            .disabledTextBox {
            background-color: white;
            border: 1px solid;
            color: black;
            cursor: default;
            width: 90px;
            display: table;
            padding: 5px 1px;
            text-align:right;
            }  
            tr .totalRow:first-child{
            text-align:left !important;
            }
            .totalRow
            {
            text-align:right;
            }
            .closeButton {
            float: right;
            }
        </style>
        
            
            <apex:commandButton value="Multi Field Sort" action="{!MultiFieldSort}" rerender="popup" status="status"/>
            
            <apex:outputPanel id="popup">
                <apex:outputPanel id="popInnerOutputPnl" styleClass="customPopup" layout="block" rendered="{!displayPopUp}">
                    
                    <apex:pageBlock >
                        
                        <apex:pageBlockButtons location="top" >
                            <apex:commandButton style=" align:right; margin-top: -28px; margin-right: -30px;border: none;" value="X" title="Close the popup" action="{!closePopup}" styleClass="closeButton" rerender="popup"/>
                            <a class="btn" style="text-decoration: none; margin-left: -146px; padding: 5px 5px 5px 5px;" onclick="AddNewRow();">Add Level</a>
                            <!--<apex:commandbutton style="margin-left: -149px;" value="Add Level" action="{!addrow}" immediate="true" rerender="ref"/>-->
                        </apex:pageBlockButtons>
                        
                        
                        <apex:pageblocktable value="{!sortwrapperList}" var="swp" id="ref">
                            <apex:variable value="{!0}" var="cnt"/>
                            <apex:column >
                                {!swp.sortby}
                            </apex:column>
                            <apex:column headerValue="Column">
                                <apex:selectList id="sortselect" multiselect="false" size="1" value="{!swp.sortselect}" style="margin-left:46px;">
                                    <apex:selectOptions value="{!sortList}" />
                                </apex:selectList>
                            </apex:column>
                            <apex:column headerValue="order">
                                <apex:selectList id="orderselect" multiselect="false" size="1" value="{!swp.orderselect}" style="margin-left:25px;">
                                    <apex:selectOptions value="{!orderList}" />
                                </apex:selectList>
                            </apex:column>
                            <apex:column headervalue="Action">
                                <a style="cursor: pointer; text-decoration: none;" onclick="removerow('{!cnt}');">Remove</a>
                                <apex:variable var="cnt" value="{!cnt+1}"/>        
                            </apex:column>
                        </apex:pageblocktable>
                    </apex:pageBlock>
                    <apex:commandbutton style="position: absolute; right: 50%;width: 50px; height: 27px;" value="OK" action="{!ok}"/>
                </apex:outputPanel>
            </apex:outputPanel>
            
            <apex:outputPanel id="panelId">
                <apex:pageBlock >
                <apex:pageblockTable value="{!wrapperList}" var="wrapRec" >
                       <!-- <apex:column styleClass="actionColumn" headerValue="Action">
                            <a href="/{!wrapRec.myId.Id}/e?retURL={!wrapRec.myId.Id}"  target="_parent" class="actionLink">Edit</a>
                            &nbsp;|&nbsp;
                            <a href="/{!wrapRec.myId.Id}"  target="_parent" class="actionLink">View</a>
                            <apex:facet name="footer">
                                Sub Total
                            </apex:facet>
                        </apex:column>-->
                        <apex:column style="text-align:center;width:92px;" value="{!wrapRec.Count}">
                            <apex:facet name="header">
                                <a style="cursor: pointer;"  onclick="sortcolumn('1','{!IF(Order=='asc', 'desc', 'asc')}');" >      
                                    Number {!IF(fieldname=='1',IF(Order=='desc','↡','↟'),'')}</a> 
                            </apex:facet>
                        </apex:column>
                        <apex:column style="text-align:center; width:99px;" value="{!wrapRec.Name}">
                            <apex:facet name="header">
                                <a style="cursor: pointer;"  onclick="sortcolumn('2','{!IF(Order=='asc', 'desc', 'asc')}');" >      
                                    Name {!IF(fieldname=='2',IF(Order=='desc','↡','↟'),'')}</a> 
                            </apex:facet>
                        </apex:column>
                        <apex:column style="text-align:center; width: 98px;" value="{!wrapRec.email}">
                            <apex:facet name="header">
                                <a style="cursor: pointer;"  onclick="sortcolumn('3','{!IF(Order=='asc', 'desc', 'asc')}');" >      
                                    email {!IF(fieldname=='3',IF(Order=='desc','↡','↟'),'')}</a> 
                            </apex:facet>
                        </apex:column>
                        <apex:column style="text-align:center; width: 98px;" value="{!wrapRec.industry}">
                            <apex:facet name="header">
                                <a style="cursor: pointer;"  onclick="sortcolumn('4','{!IF(Order=='asc', 'desc', 'asc')}');" >      
                                    phone {!IF(fieldname=='3',IF(Order=='desc','↡','↟'),'')}</a> 
                            </apex:facet>
                        </apex:column>
                        </apex:pageblockTable>
                  
                     </apex:pageBlock>
                
                    
                    
                </apex:outputPanel> 
           
       
        
        <apex:actionFunction name="addrow" action="{!addrow}" reRender="ref"/>
        <apex:actionFunction name="removelevel" action="{!removelevel}" rerender="ref">
            <apex:param name="obj" value="" assignTo="{!index}"/>   
        </apex:actionFunction>
        <apex:actionFunction name="sortheader" action="{!sortheader}" rerender="panelId">
            <apex:param name="obj1" value="" assignTo="{!fieldname}"/>
            <apex:param name="obj2" value="" assignTo="{!order}"/>
        </apex:actionFunction>
    </apex:form>
    <script>
    function jump(){
        $("body, html").animate({
            scrollTop: ($('.jumper123').first().offset().top)
        }, 1000);
    }
    function paginationnum(){  
        setPagecount();
        
    }
    function AddNewRow(){  
        addrow();
    }
    function removerow(obj) {
        removelevel(obj);
    }
    function sortcolumn(obj1, obj2) {
        sortheader(obj1, obj2);
    }
    </script>
</apex:page>

Controller:

public class compare1_sorting {
  public Id Accid;
    public string index{get; set;}
    public string fieldname{get; set;}
    public string order{get; set;}
    public string AccountName{get; set;}
    public string Affiliationfilter{get; set;}
    public string GAUfilter{get; set;}
    public string CampaignNamefilter{get; set;}
    public string filter{get; set;}
    public List<myWrapperClass> wrapperList {get; set;}
    public List<sortWrapperClass> sortwrapperList {get; set;}
    public static Map<string, string> sortMap= new Map<string, string>();
    public Boolean displayPopup {get;set;}
    public decimal pagetotalAmount{get;set;}
    public decimal pagetotalPipelineAmount{get;set;}
    public decimal totalAmount{get;set;}
    public decimal totalPipelineAmount{get;set;}
    public integer Recordcount{get;set;}
    public integer sortcount=1;
    public string paginationselect{get; set;}
    //public List<myWrapperClass> pagewrapperList {get; set;}
    Map<integer,List<myWrapperClass>> mapOpportunityPages = new Map<integer,List<myWrapperClass>>(); 
    public integer intPageNumber{get;set;} 
    public integer intNumberofPages{get;set;}
    List<Account> acclst;
    public compare1_sorting(){
         order='asc';
         wrapperList= new List<MyWrapperClass>();
        acclst= [Select name , Email__c, Industry from account limit 10];
        system.debug('acc==========='+acclst);
        integer i=0;
        for(Account acc: acclst){
        i++;
        wrapperList.add(new myWrapperClass(i, acc.name, acc.email__c, acc.Industry));
        }
        wrapperList.sort();
        system.debug('wrapperList==========='+wrapperList);
    }
    public void Applyfilter(){
         //wrapperList.add(new myWrapperClass(id1, Aff1, gdate1, gtype1, amount1, TotalSplitamount1, PipelineAmount1, camp1, GAU1, createddated1 ));
               
       // wrapperList.sort();
        
        
    }
    public void MultiFieldSort(){
        sortcount=1;
        displayPopup = true;
        sortwrapperList= new List<sortWrapperClass>();
        sortwrapperList.add(new sortWrapperClass('Sort by','',''));
    }
    public void sortheader(){
        sortwrapperList= new List<sortWrapperClass>();
        system.debug('fieldname==='+fieldname+'order========='+order);
        sortwrapperList.add(new sortWrapperClass('Single', fieldname, order));
        for(sortWrapperClass swp:sortwrapperList){
            sortMap.put(swp.sortselect, swp.orderselect);
        }
        wrapperList.sort();
        
    }
    
    public void closePopup() {
        displayPopup = false;
    }
    
    public void addrow(){
        sortcount=sortcount+1;
        if(sortcount<9)
            sortwrapperList.add(new sortWrapperClass('Then by','',''));
    }
     Public List<SelectOption> getsortList(){
        List<SelectOption> sortOptions = new List<SelectOption>();
        sortOptions.add(new SelectOption('1','Number'));
        sortOptions.add(new SelectOption('2','Name'));
        sortOptions.add(new SelectOption('3','email'));
        sortOptions.add(new SelectOption('4','Phone'));
        return sortOptions;
    }
     Public List<SelectOption> getorderList(){
        List<SelectOption> filterOptions = new List<SelectOption>();
        filterOptions.add(new SelectOption('asc', 'ASC'));
        filterOptions.add(new SelectOption('desc', 'DESC'));
        return filterOptions;
    }
    
    public void removelevel(){
        sortcount=sortcount-1;
        Integer indexVal = Integer.valueof(index);
        if(sortwrapperList[indexval -1]!= null && indexVal>1)
            sortwrapperList.remove(indexval-1);            
    }
     public void ok(){
        fieldname='';
        displayPopup = false;
        system.debug('sortwrapperList========='+sortwrapperList);
        for(sortWrapperClass swp:sortwrapperList){
            sortMap.put(swp.sortselect, swp.orderselect);
        }
        
       wrapperList.sort();
    }
    public class sortWrapperClass{
        public string sortselect{get; set;}
        public string orderselect{get; set;}
        public string sortby{get; set;}
        public sortWrapperClass(string by1, string sortselect1, string orderselect1){
            this.sortby=by1;
            if(by1=='Single'){
                this.sortselect=sortselect1;
                this.orderselect=orderselect1;
            }
            else{    this.sortselect=sortselect;
                 this.orderselect=orderselect;
                }
        }
    }
     public class myWrapperClass implements Comparable{
      public integer count{get; set;}
      public string name{get; set;}
      public string email{get; set;}
      public string industry{get; set;}
      public myWrapperClass(integer num, string nam, string emailid, string indus){
           this.count=num;
           this.name=nam;
           this.email=emailid;
           this.industry=indus;
      }
           public Integer compareTo(Object compareTo) {
           myWrapperClass compareToEventTask = (myWrapperClass)compareTo;
            if(sortMap.size()==0){
                if (count== compareToEventTask.count) 
                    return 0;
                if (count> compareToEventTask.count) 
                    return 1;
                else
                    return -1;
            }
            else if(sortMap.size()>0){
                for(string srt:sortMap.keySet()){
                    if(srt=='1'){
                        if (count<compareToEventTask.count) 
                            return sortMap.get('1')=='asc'?-1:1;
                        if (count> compareToEventTask.count) 
                            return sortMap.get('1')=='asc'?1:-1;
                        
                    }
                    if(srt=='2'){
                        if (name<compareToEventTask.name) 
                            return sortMap.get('2')=='asc'?-1:1;
                        if (name> compareToEventTask.name) 
                            return sortMap.get('2')=='asc'?1:-1;
                        
                    }
                    if(srt=='3'){
                        if (email<compareToEventTask.email) 
                            return sortMap.get('3')=='asc'?-1:1;
                        if (email> compareToEventTask.email) 
                            return sortMap.get('3')=='asc'?1:-1;
                        
                    }
                    if(srt=='4'){
                        if (industry<compareToEventTask.industry) 
                            return sortMap.get('4')=='asc'?-1:1;
                        if (industry> compareToEventTask.industry) 
                            return sortMap.get('4')=='asc'?1:-1;
                        
                    }
                    }
                    }
                    return 0;
                    }
     }
}

Leave a Reply

Your email address will not be published. Required fields are marked *