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
bappabappa 

sort by column header on vf for list view controller

Hi ,

I would like to implement sorting in VF column header for list views of Opportunity.I have used StandardSetController for this, the getRecords() method working very fine while changing the list views.But list returned from getRecords() is immmutable and i am not able to change or sort while clicking on any column header.Thought of using SOQL queries for each List view and sort using order by clause, but there the problem is for every users' list views may differ.So generating dynamic SOQL according to logged in users list view on Opportunity : if you have any idea in this please help.

Please also share any idea/thought related to sort a vf page by column header for list view controller.

MY Page is :
<apex:page standardController="Opportunity" recordSetVar="opportunities" tabStyle="Opportunity" sidebar="false" extensions="OppRecordSetVarController4" >
    <style>
        div.hideCurrDate span.dateInput span.dateFormat{
           display:none;
        }   
        
    </style> 

    <apex:stylesheet value="{!URLFOR($Resource.Spinner, 'spinner.css')}"/>
    <apex:includeScript value="{!URLFOR($Resource.Spinner, 'jquery.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.Spinner, 'spinner.js')}"/>
    <div class="splashStatus" id="splashDiv">
    <div class="circle"><img src="{!URLFOR($Resource.Spinner, 'spinner.gif')}"/></div>
    <div class="txt">Please Wait. Loading...</div>
    </div>
    <body>  
    <apex:form id="theForm">
        
        <apex:pageBlock id="thePageblock" >
            <apex:pageMessages />           

            <apex:pageBlockButtons location="bottom" id="paginationButtons">
                <apex:commandButton value="First" action="{!doFirst}" disabled="{!!HasPrevious}" />
                &nbsp;&nbsp;
                <apex:commandButton value="Previous" action="{!doPrevious}" disabled="{!!HasPrevious}" />
                &nbsp;&nbsp;
                <apex:commandButton value="Next" action="{!doNext}" disabled="{!!hasnext}" />
                &nbsp;&nbsp;
                <apex:commandButton value="Last" action="{!doLast}" disabled="{!!hasnext}" />
            </apex:pageBlockButtons>
            
            <apex:pageBlockButtons location="top" >                         
            <apex:outputLabel value="Select View:" id="theOutputLabel"/>       
            <apex:actionStatus id="splashStatus" onstart="startSplash();" onstop="endSplash();" />
            
            <apex:selectList value="{!filterId}" size="1">                 
                <apex:actionSupport event="onchange" rerender="thePageblock" status="splashStatus" />
                <apex:selectOptions value="{!listviewoptions}"/>                                      
            </apex:selectList>
            
            <apex:commandButton value="Save" action="{!doSave}"/>
            <apex:commandButton value="Cancel" action="{!doCancel}"/>
            </apex:pageBlockButtons>
            
            <apex:pageBlockTable value="{!opportunities}" var="opp" id="list1" >           

                <td><apex:column headerValue="Account Name">
                <apex:outputLink value="/{!opp.Account.Id}">{!opp.Account.Name}</apex:outputLink>
                </apex:column></td>
                <td><apex:column headerValue="Opportunity Name">
                <apex:facet name="header">
                <apex:commandLink action="{!ViewData}" value="Opportunity Name{!IF(sortExpression=='Name',IF(sortDirection='ASC','▲','▼'),'')}" reRender="thePageblock" >
                    <apex:param value="Name" name="column" assignTo="{!sortExpression}" ></apex:param>
                </apex:commandLink>
                </apex:facet>
                <apex:outputLink value="/{!opp.id}">{!opp.Name}</apex:outputLink>
                </apex:column></td>
                <apex:column headerValue="Stage" >
                <apex:actionRegion >                
                    <apex:inputField value="{!opp.stageName}" style="width:90px">
                        <apex:actionSupport event="onchange" action="{!changeStageName}" reRender="probabilityInput" status="PStatus" />
                        <!-- <apex:param value="{!opp.stageName}" assignTo="{!selectedOppStage}"/> -->
                    </apex:inputfield>                 
                </apex:actionRegion> 
                </apex:column> 
                          
                <td ><apex:column headerValue="P(%)" id="probability"> 
                    <apex:actionStatus startText="Loading.." id="PStatus" />                 
                    <apex:inputField value="{!opp.Probability}" style="text-align:center;width:50px" id="probabilityInput"/>
                </apex:column>
                </td>

                <td><apex:column headerValue="Excl." >
                    <apex:inputField value="{!opp.Exclude_From_Forecast__c}" style="width:30px"/>
                </apex:column></td>
                <td ><apex:column headerValue="W/Amount" >
                    <apex:inputField value="{!opp.ExpectedRevenue}" style="text-align:right;width:60px" />
                </apex:column>
                </td>
                <apex:column headerValue="PO Date">
                <apex:facet name="header">
                <apex:commandLink action="{!ViewData}" value="PO Date{!IF(sortExpression=='PO Date',IF(sortDirection='ASC','▲','▼'),'')}"  reRender="thePageblock">
                    <apex:param value="PO Date" name="column" assignTo="{!sortExpression}" ></apex:param>
                </apex:commandLink>
                </apex:facet>
                <div class="hideCurrDate">
                    <apex:inputField value="{!opp.closeDate}" />
                </div>
                </apex:column>                
     
                <apex:column headerValue="D2Inv">
                    <apex:inputField value="{!opp.Days_to_Invoice__c}" style="text-align:center;width:30px"/>
                </apex:column>
                <apex:column headerValue="Invoice date">
                <div class="hideCurrDate">    
                    <apex:inputField value="{!opp.Invoice_Date__c}" style="width:70px"/>
                </div>    
                </apex:column>
                <apex:column headerValue="Access">
                    <apex:inputField value="{!opp.Access__c}" style="text-align:right;width:60px"/>
                </apex:column> 
                <apex:column headerValue="Video">
                    <apex:inputField value="{!opp.Video__c}" style="text-align:right;width:60px"/>
                </apex:column>   
                <apex:column headerValue="Fire">
                    <apex:inputField value="{!opp.Fire__c}" style="text-align:right;width:60px"/>
                </apex:column> 
                <apex:column headerValue="Intrusion">
                    <apex:inputField value="{!opp.Intrusion__c}" style="text-align:right;width:60px"/>
                </apex:column>   
                <apex:column headerValue="Fiber">
                    <apex:inputField value="{!opp.Fiber__c}" style="text-align:right;width:60px"/>
                </apex:column>        
                <apex:column headerValue="Key Mgmt">
                    <apex:inputField value="{!opp.Key_Management__c}" style="text-align:right;width:60px"/>
                </apex:column>
                <apex:column headerValue="Services">
                    <apex:inputField value="{!opp.Services__c}" style="text-align:right;width:60px"/>
                </apex:column>
                
                <apex:column headerValue="Other">
                    <apex:inputField value="{!opp.Other__c}" style="text-align:right;width:60px"/>
                </apex:column>
               <!-- <apex:column headerValue="Fire D&A">
                    <apex:inputField value="{!opp.Fire_D_A__c}" style="width:60px"/>
                </apex:column>  -->
                <!-- <apex:column headerValue="FireD&A HighHazards">
                    <apex:inputField value="{!opp.Fire_D_A_High_Hazards__c}" style="width:60px"/>
                </apex:column> -->
   
                <!-- <apex:column headerValue="Suppression">
                    <apex:inputField value="{!opp.Suppression__c}" style="width:60px"/>
                </apex:column>  --> 

            </apex:pageBlockTable>            
            
           
        </apex:pageBlock>
    </apex:form>
    </body>
    <div class="lightbox"></div>
</apex:page>

My class is ; 
public with sharing class OppRecordSetVarController4 {  
    
    private final Integer pageSize = 5;
    public integer pageNumber = 1; 
    public boolean lastPage = false;
    private final String Could_Not_Save_Modified_Records = 'You have changed some values of the below records but did not save, please review the changes and "Save" the records then proceed.Otherwise “Cancel” to discard all pending changes.'; 
    public transient Map<String, Decimal> probabilityStageNameMap;   
    ApexPages.StandardSetController controller;
    ApexPages.StandardSetController controller2;
    public List<Opportunity> oppList{get;set;}
    PageReference pg;
    public boolean pbt1{get;set;}
    public boolean pbt2{get;set;}
    private String sortDirection = 'ASC';
    private String sortExp = 'name';
    public List<Opportunity> sortedOppList{get;set;}
    public Set<Opportunity> sortedOppSet {get;set;}
   
    
    public OppRecordSetVarController4(ApexPages.StandardSetController controller) {  
        this.controller = controller;
        controller.setPageSize(pageSize);
        oppList = new List<Opportunity>(); 
        //oppList = controller.getRecords(); 
       // pbt1 = true;
        //pbt2= false;  
        
        //while(controller.getHasNext()){
        
           // for(Opportunity o: (List<Opportunity>) controller.getRecords()){
                //oppList.add(o);
            //}
            //controller.next();            
        //}  
        
        getoppList();
    } 
    
    //**** Sorting Properties Starts****//
    public String sortExpression
    {
     get
     {
        return sortExp;
     }
     set
     {
       //if the column is clicked on then switch between Ascending and Descending modes
       if (value == sortExp)
         sortDirection = (sortDirection == 'ASC')? 'DESC' : 'ASC';
       else
         sortDirection = 'ASC';
       sortExp = value;
     }
    }
    
    public String getSortDirection()
    {
    //if not column is selected 
    if (sortExpression == null || sortExpression == '')
      return 'ASC';
    else
     return sortDirection;
    }

    public void setSortDirection(String value)
    {  
      sortDirection = value;
    }
    
    
    public void doNext(){        
        try{
            controller.Next();
            //pageNumber++;
            //lastPage = false;
        }catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,Could_Not_Save_Modified_Records));
        }
    }
     
    public void doPrevious(){        
        try{
            controller.Previous();
           // pageNumber--;
            //lastPage = false;
        }catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,Could_Not_Save_Modified_Records));
        }
    }
        
    public void doFirst(){        
        try{
            controller.First();
            //pageNumber = 1;
            //lastPage = false;
        }catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,Could_Not_Save_Modified_Records));
        }
    }
        
    public void doLast(){        
        try{
            controller.Last();
            //lastPage = true; 
            //pageNumber++;
            
        }catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,Could_Not_Save_Modified_Records));
        }
    }
         
    public Boolean getHasPrevious(){             
        return this.controller.getHasPrevious(); 
    }
      
    public Boolean getHasNext(){         
        return this.controller.getHasNext();    
    } 
       
    public List<Opportunity> getOpportunities() {        
        //oppList = (List<Opportunity>) controller.getRecords();
        //System.debug('==oppList.size=='+oppList.size()); 
        return (List<Opportunity>) controller.getRecords();
    }
    
    public List<Opportunity> getOppList() {        
        oppList = (List<Opportunity>) controller.getRecords();
        System.debug('==oppList=='+oppList); 
        return oppList;
    }
    
    public PageReference changeStageName(){        
    if (probabilityStageNameMap == null) {
        probabilityStageNameMap = new Map<String, Decimal>();
        for (OpportunityStage oppStage : [Select MasterLabel, DefaultProbability
                                       From OpportunityStage]) {
           probabilityStageNameMap.put(oppStage.MasterLabel, oppStage.DefaultProbability);
        }
    }
  
    for(Opportunity op : oppList){   
    if (probabilityStageNameMap.containsKey(op.StageName)) {         
         op.Probability = probabilityStageNameMap.get(op.StageName);         
    }
    }
    return null;    
    }
    
    public void changeListView(){       
        controller.save();                   
    }
    
    public void ViewData() {
      
      pageNumber = controller.getPageNumber();
      while(controller.getHasNext()){
        
            for(Opportunity o: (List<Opportunity>) controller.getRecords()){
                oppList.add(o);
            }
            controller.next();            
      }  
      controller.setPageNumber(pageNumber);   
      //controller2 = new ApexPages.StandardSetController(oppList); 
      
    }
 
    public PageReference doSave(){   
    
    PageReference p;  
    try{
    pageNumber = controller.getPageNumber();
    p =  this.controller.save();
    //pageNumber = controller.getPageNumber();
    if(p != null){
        if(pageNumber != 1){  
            controller.setPageNumber(pageNumber -1);
            controller.next();
        }          
        //pg = ApexPages.currentPage();
        //pg.setRedirect(false);
        pg = new PageReference('/apex/OppListViewVFv3');

        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM, 'Records saved successfully!!')); 
        //}  
    }
    }catch(Exception exx){
        ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'An error occured on the page.Please try again reloading the page.'));
    }
    return null;    
    } 
    
    public PageReference doCancel(){ 
    PageReference pgc;
   
    PageReference p =  this.controller.cancel();
    if(p != null){
        pgc = new PageReference('/apex/OppListViewVF');
    }
        return pgc;
    }
        
}



Thanks,
Bappa
 
ShashankShashank (Salesforce Developers) 
These links might help you:
https://help.salesforce.com/apex/HTViewSolution?id=000171025&language=en_US
http://www.sundoginteractive.com/sunblog/posts/a-recipe-for-column-sorting-salesforce-visualforce-page
bappabappa
Hi Shashank ,

Thanks for your response. actually in my implementation the SOQL queries are not fixed, because list views varies user to user , I would like to get the related dada acoording to list views , like if a user made a list view 'where opportunity region is India' , I am able to get all the custom list view records via StandardSetController.getRecords() but can not sort them like by Opoortunity name DESC. StandardSetController.getListViewOptions()  gives me some listviewID but how can I use them in SOQL query to get the relevant from opportunity? 
PreeSFDCDevPreeSFDCDev
Hi Bappa,

Are you able to resolve this? I am facing the same issue.
Created a VF page which is showing the list views using getListOptions() of standard set controller.
I am able to show the records on the basis of list view selected. However sorting is not working.
It is always sorting the records by name asc.

Please share the logic if you are able to resloved this. It will be helpful

Thanks!