How to access ListView in Apex | Using StandardSetController for Pagination

There are scenario in project lifecycle where developer creates SOQL or Dynamic SOQL to return expected result. Also if requirement changes they go back and change existing code to reflect updated SOQL. If you are good developer and avoid to change Apex code at most you will save your SOQL in “Custom Settings” and utilize in Dynamic SOQL.

However, There is very good design Developer can suggest to client. Instead of going to your code and changing code for new requirement, how it sounds if we can utilize existing List View inside Apex or Visualforce only 🙂 ? It will solve lots of problems and if requirement changed, just change or create new Listview and it will reflect in your Visualforce code. We can almost have same functionality like Navigation buttons and Paging without writing any complex code logic, thanks to StandardSetController capabilities.

There is also very good article on Salesforce blog on various approaches suggested for pagination and one of them is using StandardSetController.

To keep article simple, I am posting complete Visualforce and Apex code with Comments inside. Account object is used as an example here.

Use ListView in Visualforce with Paging and Navigation
Use ListView in Visualforce with Paging and Navigation

Apex class :

/**
*  Description : Controller Class to show How to utilize existing List View in Apex with Pagination Support
*
*  Author : Jitendra Zaa
*/
public with sharing class ListViewDemo {

  private String baseQuery = 'Select ID, Name FROM Account ORDER BY NAME ASC';
  public String AccFilterId {get; set;}
  private Integer pageSize = 10;

  public ListViewDemo(){}

  public ApexPages.StandardSetController AccSetController {
        get{
            if(AccSetController == null){
                AccSetController = new ApexPages.StandardSetController(Database.getQueryLocator(baseQuery));
                AccSetController.setPageSize(pageSize);

                // We have to set FilterId after Pagesize, else it will not work
                if(AccFilterId != null)
                {
                  AccSetController.setFilterId(AccFilterId);
                }
            }
            return AccSetController;
        }set;
    }

  public ListViewDemo(ApexPages.StandardSetController c) {   }

    //Navigate to first Page
    public void firstPage()
    {
      AccSetController.first();
    }

    //Navigate to last Page
    public void lastPage()
    {
      AccSetController.last();
    }

    //Navigate to Next page
    public void next()
    {
      if(AccSetController.getHasNext())
      {
        AccSetController.next();
      }
    }

    //Navigate to Prev Page
    public void prev()
    {
      if(AccSetController.getHasPrevious())
      {
        AccSetController.previous();
      }
    }

    public List<Account> getAccounts()
    {
      return (List<Account>)AccSetController.getRecords();
    }

    //Get all available list view for Account
    public SelectOption[] getAccountExistingViews(){
        return AccSetController.getListViewOptions();
    }

    /**
    * Reset List View
    */
    public PageReference resetFilter()
    {
      AccSetController = null;
        AccSetController.setPageNumber(1);
        return null;
    }

}

Visualforce Page:

<apex:page controller="ListViewDemo">
Available List Views for Account :
  <apex:form id="pageForm">
   	   <apex:selectList value="{!AccFilterId}" size="1" id="filterMenu">
     		<apex:selectOptions value="{!AccountExistingViews}"></apex:selectOptions>
     		<apex:actionSupport event="onchange"  action="{!resetFilter}" rerender="AccntTable" status="ajaxStatus"/>
   	   </apex:selectList>

   	   <apex:actionStatus id="ajaxStatus" startText="Loading..."  stopText=""/>

   	 <apex:pageBlock title="Accounts">
   	    <apex:pageBlockButtons >
                <apex:commandButton action="{!firstPage}" value="|<<" reRender="AccntTable"  status="ajaxStatus" />
                <apex:commandButton action="{!prev}" value="<" reRender="AccntTable"  status="ajaxStatus" />
                <apex:commandButton action="{!next}" value=">" reRender="AccntTable"  status="ajaxStatus" />
                <apex:commandButton action="{!lastPage}" value=">>|" reRender="AccntTable"  status="ajaxStatus" />
            </apex:pageBlockButtons>

	        <apex:pageBlockTable value="{!Accounts}" var="item" id="AccntTable">
	            <apex:column value="{!item.name}"/>
	        </apex:pageBlockTable>
     </apex:pageBlock>
   </apex:form>
</apex:page>

Test Class :

@isTest
public class ListViewDemoTest
{    
    
    @testSetup 
    static void createAccount() {
        // Create common test accounts
        List<Account> testAccts = new List<Account>();
        for(Integer i=0;i<20;i++) {
            testAccts.add(new Account(Name = 'TestAcct'+i));
        }
        insert testAccts;        
    }
    
     public static testMethod void getListView(){
        //Lets Assume we are writing Controller extension to use on List View of Account
        List <Account> acctList = [SELECT ID FROM Account];
		
         //Check Account created count by setup()
         System.assertEquals(20,acctList.size());
         
        //Start Test Context, It will reset all Governor limits
        Test.startTest();

        //Inform Test Class to set current page as your Page where Extension is used
        Test.setCurrentPage(Page.ListViewDemo);

        //Instantiate object of "ApexPages.StandardSetController" by passing array of records
        ApexPages.StandardSetController stdSetController = new ApexPages.StandardSetController(acctList);

        //Now, create Object of your Controller extension by passing object of standardSetController
        ListViewDemo ext = new ListViewDemo(stdSetController);
        
        SelectOption[] selOptions = ext.getAccountExistingViews();
         
        //We should not assert count of list View as no control over creation of list view
        //but in my Dev org, I know count is 6 
        System.assertEquals(6,selOptions.size());
         
         ext.firstPage();
         List<Account> accFirsttPage = ext.getAccounts();
         System.assertEquals( 10, accFirsttPage.size() );
         
         ext.next();
         ext.prev();
         ext.resetFilter();
         ext.lastPage();
          
        //Finish Test
        Test.stopTest();
     } 
}

Related Posts

Comments

13 responses to “How to access ListView in Apex | Using StandardSetController for Pagination”

  1. Reshma Avatar
    Reshma

    nice post..
    I wanted to know if there is a way to know where the user has edit permission for the list view?
    May be by some metadata API or something?

    1. PrSFDC Avatar
      PrSFDC

      Hi Reshma,

      Are you able to resolve the issue of having Edit permission for list view.
      If yes,can you please tell us how. I am facing the similar issue.

  2. jaya koti Avatar
    jaya koti

    Hi Jitendra,
    Shall we access List view in apex without using Standard set controller ?
    Thanks,
    Koti

    1. Jitendra Zaa Avatar

      Hi Jaya, StandardSet Controller will provide Pagination and other logics inbuilt.

      1. sk Avatar
        sk

        hi sir,
        can you please tell me how can i get list views for standard and custom objects in apex.
        basically i have created a dynamic picklist with some standard and custom objects and i have a button get details,so i want that when i press the button i get the list view of the selected object.
        any help would be appriciated

  3. PrSFDC Avatar
    PrSFDC

    Hi Jitendera,
    Thanks for sharing this code. It really helps.
    Is that possible to do sorting on the records returned from the above logic.
    If yes,can you please share

    1. Jitendra Zaa Avatar

      FOr that you would need to write custom code, Sorting is not supported by default in standard set controller.

      1. PrSFDC Avatar
        PrSFDC

        Thanks Jitendra. Have you done something like that . Please share the logic if you have done that before. It will be really helpful.

  4. Nishant Verma Avatar
    Nishant Verma

    Hi Jitendera
    Thanks for sharing this code. It really helpful.
    In above code you are using class”StandardSetController” and method “getListViewOptions()” from ‘Account’ object
    this method does not for custom object. So I need your help, how get list view for custom using this method. Please let me know ASAP.

  5. Om Avatar
    Om

    can we use standard set controllers for custom objects also?

    1. Jitendra Avatar

      yes

  6. Prachi Avatar

    Hi Jitendra,
    Nice post.
    But the line no. 77 in controller is generating following error for me : ‘The value of the “id” parameter contains a character that is not allowed or the value exceeds the maximum allowed length.’
    Great if you could help me in some way
    Thanks

  7. Sukanth Avatar
    Sukanth

    Hi Jitendra,

    I want to display only few list views instead of All (getListViewOptions), how to filter the required list views?

    Thanks in advance.

    Regards,
    Sukanth

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading