1

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?

4
  • 2
    You just need to wrap the collection elements after the fact.
    – Adrian Larson
    Commented Dec 13, 2015 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. Commented Dec 13, 2015 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
    Commented Dec 13, 2015 at 17:43
  • @AdrianLarson Thanks. I think I got it. Tried some code posting it. Commented Dec 14, 2015 at 1:03

1 Answer 1

1

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 {
        get{
            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));
                setCon.setPageSize(size);
                noOfRecords = setCon.getResultSize();
            }
            return setCon;
        }set;
    }

    public PaginationController(){
        accList = new List<AccountWrapper>();
        accountVsIsSelected = new Map<Id,Boolean>();
    }
    public List<AccountWrapper> getAccounts(){
        for(AccountWrapper theAcc : accList){
            accountVsIsSelected.put(theAcc.acc.Id,theAcc.isSelected);
        }
        accList.clear();
        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;
        getAccounts();
        setCon.setPageNumber(1);
        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.

Page:

<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>
                <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:pageBlockTable>
            <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=""/>
                </apex:outputPanel>
            </apex:panelGrid>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Output: enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .