Pagination and the StandardSetController – No Custom Controller Required

When I designed the code for my online course for lynda.com called “Developing with Visualforce“, I looked for solutions that were as simple as possible. After all, even I will admit that developers do tend to over complicate things unnecessarily.

One of the areas I was covering was handling multiple records and therefore pagination was introduced. In my research for the course, I uncovered dozens of posts/tutorials by developers using Custom Controllers or Extensions to implement this functionality. For a while I thought this was the only way it could be done. Since the underlying message for my course was to find the simplest solution possible, I am glad I dug a little farther and found a way to provide the necessary pagination without the need for a custom controller.

I discovered this while reading through the very excellent online resource titled, “Visualforce in Practice“. This very practical guide was published in 2013 and it contains many tips for development that were discovered through years of practice. Chapter 4 of this guide covers the Standard List Controller and the corresponding StandardSetController. What it revealed was that despite the fact that even the Salesforce documentation leads you to believe that you need a custom controller extension to change the page size, this is not actually. true. You can in fact do it using just the Standard Controller and referencing PageSize member variable. You can then change the page size by adding a command button with a NULL action to force the controller to update.

For example, the page that I created for the course, displayed multiple opportunities that could be edited by the user (see Figure below). At the bottom of the page, I included buttons to page the user through the results, but I also wanted to include a way for the user to change the default of 20 records per page.

EditOpportunities

This was accomplished by simply adding standard apex controls to the bottom of the page. No custom controller or extension required. All the code needed to produce the page you see above is as follows:

 <apex:page standardController="Opportunity" recordSetVar="opportunities" tabStyle="Opportunity">
    <apex:form >
        <apex:pageBlock title="Edit Opportunities" >
            <apex:pageMessages ></apex:pageMessages>
            <apex:pageBlockButtons >
              <apex:commandButton value="Save" action="{!save}"/>
              <apex:commandButton value="Cancel" action="{!cancel}"/>
            </apex:pageBlockButtons>
            <apex:pageBlockTable value="{!opportunities}" var="opp">
                <apex:column value="{!opp.name}"/>
                  <apex:column headerValue="Stage">
                    <apex:inputField value="{!opp.stageName}"/>
                  </apex:column>
                  <apex:column headerValue="Close Date">
                    <apex:inputField value="{!opp.closeDate}"/>
                  </apex:column>
            </apex:pageBlockTable>
            <apex:panelGrid cellpadding="5" cellspacing="5" columns="5" >
                <apex:commandButton value="|<" action="{!first}"  />
                <apex:commandButton value="<" action="{!previous}" rendered="{!HasPrevious}" />
                <apex:commandButton value=">" action="{!next}" rendered="{!HasNext}" />
                <apex:commandButton value=">|" action="{!last}"  />
                <apex:panelGroup >
                    <apex:outputText value="Records/Page"></apex:outputText>&nbsp;&nbsp;
                    <apex:selectList value="{!PageSize}" size="1">
                        <apex:selectOption itemValue="10" itemLabel="10"></apex:selectOption>
                        <apex:selectOption itemValue="15" itemLabel="15"></apex:selectOption>
                        <apex:selectOption itemValue="20" itemLabel="20"></apex:selectOption>
                    </apex:selectList>&nbsp;&nbsp;
                    <apex:commandButton action="{!NULL}" value="Update Page Size"/>
                </apex:panelGroup>
           </apex:panelGrid>
         </apex:pageBlock>
    </apex:form>
</apex:page>

I very much prefer this solution to the one that requires a custom controller. It is easier to maintain and does not involve creating unit tests to deploy. Hope this helps someone else to not over complicate code they are creating. If you are interested in learning more, check out my online course for lynda.com called, “Developing with Visualforce“.