Salesforce | Handling View state problem

|
| By Webner

Display more than 10,000 records by Handling View state problem (only 132 kb data displayed on vf page).

Problem statement : Displaying more than 50,000 records in the table.

Solution : This issue has been resolved by pagination of the table.

Apex class :

  1. Create a two wrapper list one for fetch all records from Salesforce and the second to display records in Vf page (Number of records visible on single page of the table).
  2. Records are fetched according to index and set in the display list.
  3. Clear main list to avoid viewstate problem.

Code for Apex Controller :

public class TableTest
{
  private Integer pageNumber; // determines the current page number
  private Integer pageSize; // pageSize determines the number of records to display.
  private Integer totalPageNumber; //Number of page required to display all records
  private Integer totalsize; // Total Number of records
  public List<Account> wrapDetailList {get; set;} //Account list to display the current set of records
  public List<Account> wrapDetailListmain {get; set;} // get all Account record list.

public TableTest()
 {
   pageNumber = 0;
   totalPageNumber = 0;
   pageSize = 20;
   ViewData();
  }
//initially called
public PageReference ViewData()
{
   wrapDetailListmain = null;
   totalPageNumber = 0;
   BindData(1);
   return null;
} 

// Get records and maintain a list to display current set of records using offset
private void BindData(Integer newPageIndex)
 {
    if(wrapDetailListmain == null) 
     {
       wrapDetailListmain = new List<Account>();
       wrapDetailListmain =[select id,name from Account];
       totalsize=wrapDetailListmain.size();

        if(wrapDetailListmain.isEmpty())
          {
           ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'No record available'));
           }
     }
       wrapDetailList= new List<wrapdDetail >();
       Transient Integer counter = 0;
       Transient Integer min = 0;
       Transient Integer max = 0;
       if (newPageIndex > pageNumber)
         {
         min = pageNumber * pageSize;
         max = newPageIndex * pageSize;
      }else
    {
        max = newPageIndex * pageSize;
        min = max - pageSize;
    }
     List<String> ls=new List<String>();
     for(Account a : wrapDetailListmain)
     {
        Counter++;
        if (counter > min && counter <= max){
        wrapDetailList.add(a);
      }
     pageNumber = newPageIndex;
     wrapDetailListmain.clear(); //clear main list here
  if (wrapDetailList== null || wrapDetailList.size() <= 0)
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Data not available for this view.'));
 }  
 //get next record set 
public PageReference previousBtnClick() 
{
    BindData(pageNumber - 1);
    return null;
}
//get current page number

public Integer getPageNumber()
 {
   return pageNumber;
 }
public List<Account> getwrapDetailData()
 {
  return wrapDetailList;
 }
// Number of records display in one page
public Integer getPageSize()
{
return pageSize;
}
//Diables the previous buttons if there is no record previous than current list
public Boolean getPreviousButtonEnabled()
{
  return !(pageNumber > 1);
}
//Diables the next buttons if there is no record next to current list
public Boolean getNextButtonDisabled()
{
   if (wrapDetailListmain== null) { 
     return true;
   }
  Else
  {
    return ((pageNumber * pageSize) >= totalsize);
  }
}
//calculate number of pages according to total records
public Integer getTotalPageNumber()
{
   if (totalPageNumber == 0 && wrapDetailListmain!=null)
  {
    totalPageNumber = totalsize / pageSize;
    Integer mod = wrapDetailListmain.size() - (totalPageNumber * pageSize);
     if (mod > 0)
     totalPageNumber++;
  }
  return totalPageNumber;
}
 //get previous record set 
public PageReference nextBtnClick()
 {
  BindData(pageNumber + 1);
   return null;
}

 VisualForce page  :

1. To implementing pagination we are using two buttons pre and next.

2. On click of pre and next button page number is sent to controller through which we know further which page records are to be fetched.

3. There are two more methods (previousButtonEnabled, nextButtonDisabled) which are used to enable or disable these buttons.

Code  :

<apex:page controller="TableTest" title="TableTest" sidebar="false">
 <apex:includescript value="//code.jquery.com/jquery-1.11.1.min.js" / >
 <apex:form id="frm">
    <apex:pageBlock id="pageBlock">
       <apex:pageMessages />
   <div align="right" style="display:{!IF(NOT(ISNULL(wrapDetailData)),'block','none')}">
<font size="1pt">Page #:&nbsp;<apex:outputLabel value="{!PageNumber}"/>&nbsp;out of&nbsp;<apex:outputLabel value="{!totalPageNumber}"/>&nbsp;&nbsp;&nbsp;&nbsp;</font>
<apex:commandButton value="Previous" action="{!previousBtnClick}" disabled="{!previousButtonEnabled}"reRender="pageBlock"></apex:commandButton>
<apex:commandButton value="Next" action="{!nextBtnClick}" reRender="pageBlock" disabled="{!nextButtonDisabled}" ></apex:commandButton>
</div>
         <apex:pageBlockTable value="{!wrapDetailList}" var="accWrap" id="reconciletable" >
      <apex:column headerValue="ID" headerClass="ct" value="{!accWrap.Id}" />
     <apex:column headerValue="Name" headerClass="ct" value="{!accWrap.Name}" />
          </apex:pageBlockTable>
   <div align="right" style="display:{!IF(NOT(ISNULL(wrapDetailData)),'block','none')}">
<font size="1pt">Page #:&nbsp;<apex:outputLabel value="{!PageNumber}"/>&nbsp;out of&nbsp;<apex:outputLabel value="{!totalPageNumber}"/>&nbsp;&nbsp;&nbsp;&nbsp;</font>
<apex:commandButton value="Previous" action="{!previousBtnClick}" disabled="{!previousButtonEnabled}"reRender="pageBlock"></apex:commandButton>
<apex:commandButton value="Next" action="{!nextBtnClick}" reRender="pageBlock" disabled="{!nextButtonDisabled}" ></apex:commandButton>
</div>

Leave a Reply

Your email address will not be published. Required fields are marked *