Tuesday 15 September 2015

Pagination using Extension controller in addition to the Standard Controller - Part # 3

In this post we are handling the pagination functions via extension controller in addition to the standard controller.

What is Extension Controller?

controller extension is any Apex class containing a constructor that takes a single argument of type ApexPages.StandardController or CustomControllerName , where CustomControllerName is the name of a custom controller you want to extend.

Defining Extension Controller in Visualforce page:
public ApexPages.StandardSetController con{get; set;}
public PaginationTutorial_3(ApexPages.StandardSetController controller) 
{
        this.con = controller;

}


Using Extension Controller in Visualforce page:
<apex:page standardController="Product2"  recordsetvar="products" extensions="PaginationTutorial_3">
.
.
.
.
.
.
</apex:page>


The extension is associated with the page using the extensions attribute of the <apex:page> component.


Defining more than one Extension Controller:

Multiple controller extensions can be defined for a single page through a comma-separated list. This allows for overrides of methods with the same name. For example, if the following page exists:

<apex:page standardController="Account" 
    extensions="ExtOne,ExtTwo" showHeader="false">
    <apex:outputText value="{!foo}" />
</apex:page>
public class ExtOne {
    public ExtOne(ApexPages.StandardController con) { }

    public String getFoo() {
        return 'foo-One';
    }
}

public class ExtTwo {
    public ExtTwo(ApexPages.StandardController con) { }

    public String getFoo() {
        return 'foo-Two';
    }
}

The value of the <apex:outputText> component renders as foo-One. Overrides are defined by whichever methods are defined in the “leftmost” extension, or, the extension that is first in the comma-separated list. Thus, the getFoo method of ExtOne is overriding the method of ExtTwo.

Refer below markup for more details.

Visualforce Page:


<!--
Code Name   : PaginationTutorial_3
Code Type   : Visualforce
Dependency  : PaginationTutorial_3 (Apex Class)
Description : Pagination using Extension controller in addition to the Standard Controller
Author      : Bharathimohan Ramamurthy
-->
<apex:page standardController="Product2"  recordsetvar="products" extensions="PaginationTutorial_3">
<apex:pageMessages id="pgm"/>
<apex:form >                     
<apex:pageBlock >
    <apex:outputPanel layout="block" styleClass="pSearchShowMore" id="otpNav2">
        Total Records Found: <apex:outputText rendered="{!IF(Con.resultSize==10000,true,false)}">10000 +</apex:outputText><apex:outputText rendered="{!IF(Con.resultSize < 10000,true,false)}">{!Con.resultSize}</apex:outputText>
        <apex:image url="/img/search_prevarrow_disabled.gif" styleClass="prevArrow" rendered="{!NOT(Con.HasPrevious)}"/>
        <apex:image url="/img/search_prevarrow.gif" title="Previous Page" styleClass="prevArrow" rendered="{!Con.HasPrevious}"/>
        <apex:commandLink action="{!Previous}" title="Previous Page" value="Previous Page" rendered="{!Con.HasPrevious}"/>
        <apex:outputPanel styleClass="pShowLess noLink" style="color:grey" rendered="{!NOT(Con.HasPrevious)}">Previous Page</apex:outputPanel>         
        &nbsp;({!IF(Con.PageNumber == 1,1,((Con.PageNumber -1) * Con.PageSize)+1)}-{!IF(Con.resultSize < Con.PageSize,Con.resultSize,Con.PageNumber * Con.pageSize)})&nbsp;
        <apex:outputPanel styleClass="pShowLess noLink" style="color:grey" rendered="{!NOT(Con.HasNext)}">Next Page</apex:outputPanel>         
        <apex:commandLink title="Next Page" value="Next Page" rendered="{!Con.HasNext}" action="{!Next}"/>&nbsp;
        <apex:image url="/img/search_nextarrow.gif" title="Next Page" styleClass="nextArrow" rendered="{!Con.HasNext}"/>
        <apex:image url="/img/search_nextarrow_disabled.gif" rendered="{!NOT(Con.HasNext)}"/>          
    </apex:outputPanel>            
    <apex:pageBlockTable value="{!products}" var="v">
      <apex:column value="{!v.name}"/>
      <apex:column value="{!v.IsActive}"/>
      <apex:column value="{!v.ProductCode}"/>
      <apex:column value="{!v.RecordTypeId}"/>
      <apex:column value="{!v.CreatedbyId}"/>
      <apex:column value="{!v.CreatedBy.ProfileId}"/>      
      <apex:column value="{!v.CreatedDate}"/>
    </apex:pageBlockTable>
    <apex:outputPanel layout="block" styleClass="pSearchShowMore" id="otpNav">
        Total Records Found: <apex:outputText rendered="{!IF(Con.resultSize==10000,true,false)}">10000 +</apex:outputText><apex:outputText rendered="{!IF(Con.resultSize < 10000,true,false)}">{!Con.resultSize}</apex:outputText>
        <apex:image url="/img/search_prevarrow_disabled.gif" styleClass="prevArrow" rendered="{!NOT(Con.HasPrevious)}"/>
        <apex:image url="/img/search_prevarrow.gif" title="Previous Page" styleClass="prevArrow" rendered="{!Con.HasPrevious}"/>
        <apex:commandLink action="{!Previous}" title="Previous Page" value="Previous Page" rendered="{!Con.HasPrevious}"/>
        <apex:outputPanel styleClass="pShowLess noLink" style="color:grey" rendered="{!NOT(Con.HasPrevious)}">Previous Page</apex:outputPanel>         
        &nbsp;({!IF(Con.PageNumber == 1,1,((Con.PageNumber -1) * Con.PageSize)+1)}-{!IF(Con.resultSize < Con.PageSize,Con.resultSize,Con.PageNumber * Con.pageSize)})&nbsp;
        <apex:outputPanel styleClass="pShowLess noLink" style="color:grey" rendered="{!NOT(Con.HasNext)}">Next Page</apex:outputPanel>         
            <apex:commandLink title="Next Page" value="Next Page" rendered="{!Con.HasNext}" action="{!Next}"/>&nbsp;
            <apex:image url="/img/search_nextarrow.gif" title="Next Page" styleClass="nextArrow" rendered="{!Con.HasNext}"/>
            <apex:image url="/img/search_nextarrow_disabled.gif" rendered="{!NOT(Con.HasNext)}"/>          
    </apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>

Extension Controller:


public class PaginationTutorial_3
{    
    public ApexPages.StandardSetController con{get; set;}
    public PaginationTutorial_3(ApexPages.StandardSetController controller) 
    {
        this.con = controller;
        this.con.setPageSize(10);
    }
      
    //Boolean to check if there are more records after the present displaying records
    public Boolean hasNext
    {
        get
        {
            return con.getHasNext();
        }
        set;
    } 
    //Boolean to check if there are more records before the present displaying records
    public Boolean hasPrevious
    {
        get
        {
            return con.getHasPrevious();
        }
        set;
    } 
    //Page number of the current displaying records
    public Integer pageNumber
    {
        get
        {
            return con.getPageNumber();
        }
        set;
    }
    //Returns the previous page of records
    public void previous()
    {
        con.previous();
    } 
    //Returns the next page of records
    public void next()
    {
        con.next();
    }
    
    /*
        
    public List productList
    {
        get
        {
            if(con != null)
                return (List)con.getRecords();
            else
                return null ;
        }
        set;
    } 
    
    */
}


Preview:




Pros:

  • Flexibility in handling pagination via extension controller
  • Compatible design to use Field Sets, especially for Field Sets that include relationship fields (Account.Name on opportunity etc.,). We are discussing this later in another post
  • Ideal design to retrieve and display specific set of records when using SOQL explicitly

Points to Note:

  • Like other Apex classes, controller extensions run in system mode. Consequently, the current user's credentials are not used to execute controller logic, and the user's permissions and field-level security do not apply. However, if a controller extension extends a standard controller, the logic from the standard controller does not execute in system mode. Instead, it executes in user mode, in which the permissions, field-level security, and sharing rules of the current user apply
  • You can choose whether a controller extension respects a user's organization-wide defaults, role hierarchy, and sharing rules by using the with sharing keywords in the class definition

No comments:

Post a Comment