Tuesday, June 25, 2013




Well here is a much awaited and the needed update for the PageBlockTable Enhancer plugin. Ever since I coded the first version, there were request for many features and this 2.2 version brings down some of them.

Here is what is new with this plugin
  1. Parameter to turn on and off Pagination.
  2. Support for specifying available page sizes.
  3. Support for choosing default page size on page load.

List o Parameters
  • targetPbTableIds : comma-separated Ids of the target Pageblock tables
  • paginate : Assign true if you want to use the pagination feature,default value is true.
  • pageSizeOptions : A comma seperated list of integer values that will displayed as dropdown for page size
  • defaultPageSize : Default page size that needs to be selected (at page load).
Ajax/Rerender support
  • This version brings in support for rendering, the earlier version wasn't able to handle this. So incase you are rerendering your table or the parent components, you can call the "initPageBlockTableEnhancer()" method from "oncomplete" even of your commandButtons/actionFunctions/actionSupport/commandLink .

    <apex:commandButton value="Rerender" reRender="mid" oncomplete="initPageBlockTableEnhancer()"/>
Basic Syntax
The basic syntax remains same, just few added params.

<c:PageBlockTableEnhancer targetPbTableIds="mid,mid2" paginate="true" defaultPageSize="5" pageSizeOptions="5,10,20,30,40,50,100"/>    
   <apex:pageBlock >   
     <apex:pageBlockTable value="{!accounts}" var="acc" id="mid">   
      <apex:column value="{!acc.Name}"/>   
     </apex:pageBlockTable>    
     <apex:pageBlockTable value="{!accounts}" var="acc" id="mid2">   
      <apex:column value="{!acc.Name}"/>   
     </apex:pageBlockTable>     
   </apex:pageBlock>  


Demo And Installation / Unmanaged Package: http://blogforce9dev-developer-edition.ap1.force.com/ProjectDetail?id=a0290000007rdwd
[Updated @ 27-Nov-2013 :  Bug Fixes related to sorting]

Thursday, June 6, 2013


What are wrapper classes?

Wrapper classes can be considered as user defined data types. Wrapper classes can enclose together many other variables/parameters to represent a object or a single entity. They can include primitive types, complex types, Sobject types and even other wrapper classes as their property.

Lets assume we want to define a Entity say "Student". So for this we have to define a Wrapper class "Student"with properties like RollNumber,Name,Email. The class will look like.

Public class Student{  
  public String RollNumber;  
  public String Name;  
  public String Email;  
 }  

Where we can use these wrapper classes ?

Lets consider a real life scenario where user is allowed to select some records from a pageblock table and is allowed to do some action on the selected records.

So in our case lets assume the Sobject is Account, user will be allowed to select some records from a list and say they will be allowed to delete the selected record using a button.



How to implement this ?

Well we can always fetch some records to the pageblocktable to display set of records in table, but how to bring back the selection to controller ? Well here comes the need of another property in picture which will bring back the selection to the controller. This can achieved by creating a extra checkbox field in sobject but doesnt sounds like a good plan. A new field just for selection ? well Wrapper classes will be a better option here. We will define a wrapper class with this additional property say "isSelected" and will use the same in the page.

So the wrapper class will look like

public class sObjectWrapper{  
  public boolean isSelected{get;set;}  
  public Account myAccount{get;set;}  
  public sObjectWrapper(Account myAccount,Boolean isSelected){  
   this. myAccount = myAccount;  
   this.isSelected = isSelected;  
  }  
 }  

Now how to populate this wrapper class ?

You may have to modify your code to populate List< sObjectWrapper > instead of List<SObject>. So lets say you have a method "getData" in controller that queries for the related records, you may want to modify the same to support wrappers.

So the controller will look something like this

public class WrapperDemo_Con {  
   /*List of wrappers*/  
   public List<sObjectWrapper> wrappers{get;set;}  
   /*Constructor*/  
   public WrapperDemo_Con(){  
     wrappers = getData();  
   }  
   /*method to delete the selected record*/   
   public void deleteRecords(){  
     List<Account> accToDel = new List<Account>();  
     for(sObjectWrapper wrap : wrappers){  
       /*Check if record is selected*/  
       if(wrap.isSelected){  
         accToDel.add(wrap.myAccount);  
       }  
     }  
     /*Delete the selected records*/  
     delete accToDel;  
     /*Referesh the data*/  
     wrappers = getData();  
   }  
   /*mehtod to query account and populate wrappers*/  
   private List<sObjectWrapper> getData(){  
     List<sObjectWrapper> wrappers = new List<sObjectWrapper>();  
     for(Account acc : [SELECT Name,Id,Phone, Description FROM Account]){  
       /*Create a new wrapper and add it to list*/  
       wrappers.add(new sObjectWrapper(acc,false));  
     }  
     return wrappers;  
   }  
   /*Wrapper class*/  
   public class sObjectWrapper{  
    public boolean isSelected{get;set;}  
    public Account myAccount{get;set;}  
    public sObjectWrapper(Account myAccount,Boolean isSelected){  
     this.myAccount = myAccount;  
     this.isSelected = isSelected;  
    }  
   }  
 }  

And the corresponding VF page will be

<apex:page controller="WrapperDemo_Con">  
   <apex:sectionHeader title="Demo" subtitle="Wrapper Class"/>  
   <apex:Form >  
     <apex:pageBlock title="Wrapper Demo">  
       <apex:pageBlockButtons >  
         <apex:commandButton value="Delete" action="{!deleteRecords}"/>  
       </apex:pageBlockButtons>  
       <apex:pageBlockTable value="{!wrappers}" var="wrap">  
         <apex:column headerValue="Select">            
           <apex:inputCheckbox value="{!wrap.isSelected}"/>  
         </apex:column>  
         <apex:column value="{!wrap.myAccount.name}"/>  
         <apex:column value="{!wrap.myAccount.phone}"/>  
       </apex:pageBlockTable>  
     </apex:pageBlock>  
   </apex:Form>  
  </apex:page>  


Now testing time! Select few records from the list and press the save button. The selected records should be delete d and page should reload with the current data set.

In a similar fashion you can wrap any Sobject or Even wrap another wrapper class to get desired result. May be something more complicated!