Is there a way to utilize StandardSetController for non sObjects? Here is the issue. I have an sObject wrapper class and I'd like to use StandardSetController for next, prev, first, last (i.e. for pagination). The problem is that StandardSetConroller only accepts sObjects. Is there a way to fix that?

  • 2
    You just need to wrap the collection elements after the fact. – Adrian Larson Dec 13 '15 at 5:58
  • @Adrian Larson. I tried that but it seems that it is not accepting list of wrapper instances. I think wrappers are not supported as a part of elements that can be passed to StandardSetController. I went through its doc and checked if there is any method which is based on Sobjects. There is one setFilterID(filterId) method from StandardSetController which is relied on listViewFilter ids which are only present for SObjects. It would have been great if we could pass wrapper instances. May be I am doing something wrong. Please share if you have some code base. Thanks. – Kiran Machhewar Dec 13 '15 at 9:08
  • The approach you describe is wrapping records before pagination, not after. I'll post an example tonight if no one beats me to it. – Adrian Larson Dec 13 '15 at 17:43
  • @AdrianLarson Thanks. I think I got it. Tried some code posting it. – Kiran Machhewar Dec 14 '15 at 1:03

as @Adrian Larson suggested we can use wrappers once we get elements from getRecords method. We normally use wrappers to maintain some values which are not part of SObject so here also you need to maintain state but maintaining complete information about wrapper instance against sobject id in a map would take lot of view state. So it would be better to keep only information which can be changed. Here in my example you would see one IsSelected state is maintained for every account.

Controller :

public with sharing class PaginationController {
    Public Integer noOfRecords{get; set;}
    Public Integer size{get;set;}
    public Map<Id,Boolean> accountVsIsSelected {get;set;}
    public List<AccountWrapper> accList {get;set;}
    public ApexPages.StandardSetController setCon {
            if(setCon == null){
                size = 10;
                string queryString = 'Select Name, Type, BillingCity, BillingState, BillingCountry from Account order by Name';

                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(queryString));
                noOfRecords = setCon.getResultSize();
            return setCon;

    public PaginationController(){
        accList = new List<AccountWrapper>();
        accountVsIsSelected = new Map<Id,Boolean>();
    public List<AccountWrapper> getAccounts(){
        for(AccountWrapper theAcc : accList){
        for(Account a : (List<Account>)setCon.getRecords()){
            accList.add(new AccountWrapper(a,(accountVsIsSelected.get(a.Id)==true?true:false)));

        return accList;

    public pageReference refresh() {
        setCon = null;
        return null;

    public class AccountWrapper{
        public Account acc{set;get;}
        public Boolean isSelected {get;set;}
        public AccountWrapper(Account acc,Boolean isSelected){
            this.acc = acc;
            this.isSelected = isSelected;

As you can see wrapping of Account is done when we tried to fetch accounts and also maintained state so that it could be recollected when needed.


<apex:page controller="PaginationController">
    <apex:form >
        <apex:pageBlock id="pb">
            <apex:pageBlockTable value="{!Accounts}" var="a">
                <apex:column headerValue="Action">
                    <apex:inputCheckbox value="{!a.IsSelected}" ></apex:inputCheckbox>
                <apex:column value="{!a.acc.Name}"/>
                <apex:column value="{!a.acc.Type}"/>
                <apex:column value="{!a.acc.BillingCity}"/>
                <apex:column value="{!a.acc.BillingState}"/>
                <apex:column value="{!a.acc.BillingCountry}"/>
            <apex:panelGrid columns="7">
                <apex:commandButton status="fetchStatus" reRender="pb" value="|<" action="{!setCon.first}" disabled="{!!setCon.hasPrevious}" title="First Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value="<" action="{!setCon.previous}" disabled="{!!setCon.hasPrevious}" title="Previous Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value=">" action="{!setCon.next}" disabled="{!!setCon.hasNext}" title="Next Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value=">|" action="{!setCon.last}" disabled="{!!setCon.hasNext}" title="Last Page"/>
                <apex:outputText >{!(setCon.pageNumber * size)+1-size}-{!IF((setCon.pageNumber * size)>noOfRecords, noOfRecords,(setCon.pageNumber * size))} of {!noOfRecords}</apex:outputText>
                <apex:commandButton status="fetchStatus" reRender="pb" value="Refresh" action="{!refresh}" title="Refresh Page"/>
                <apex:outputPanel style="color:#4AA02C;font-weight:bold">
                    <apex:actionStatus id="fetchStatus" startText="Fetching..." stopText=""/>

Output: enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.