How to use wrapper class in apex

Article 1** Article 2** Article 3** Article 4** Article 5** Article 6** Article 7** Article 8** Article 9 ** Article 10

Before we see an example of how wrapper class is used we should know what is wrapper class,why wrapper class is used and what makes it required.

What is a wrapper class?

A wrapper class i would say is a custom object defined by programmer wherein he defines the wrapper class properties. Consider a custom object in salesforce, what do you have in it? fields right? different fields of different data types. On similar grounds i can say wrapper class has different data types/properties as desired by the programmer. You can wrap different objects types or any other types in a wrapper class.


Why wrapper class?

Generally collections like "list" can store only one type of data for example "string' or "Account". List<Account> will hold only accounts and List<string> will hold only strings in it. But what if you want to show data on table that should show account record as well as it primary contact data  ? iterating over List<Account> will only allow account records and no contact data. 

In this case you can create a wrapper class having variables account and contact and then create list of that wrapper class. This may look a bit complicated but as you go through an example it will sort out easily.

An example i can think of is.. You want to display a account data in table along with a check box on the right side of the table(checkbox for every row) Well you can very well bind a account checkbox field to this right column but below example is for demonstrating wrapper with a custom checkbox column.


Your table value will iterate through list of wrapper class.For every account and checkbox value(false) You will be storing a new wrapper class records in the wrapper class list. This wrapper calss has properties (Account and Boolean).



-- Visualforce page --

<apex:page standardController="Account" extensions="WrapperDemoClass">
  <apex:form >
    <apex:pageblock >
      <apex:pageblockTable value="{!wrapperObj}" var="Rec">
         <apex:column value="{!Rec.accObj.name}"/>
         <apex:column >
            <apex:inputcheckbox value="{!Rec.checkBox}"/>
         </apex:column>
      </apex:pageblockTable> 
    </apex:pageblock>
    </apex:form>
</apex:page>


-- Controller used --

public with sharing class WrapperDemoClass {
 Public List<WrapperClassEx> WrapperList{get;set;}
    public WrapperDemoClass(ApexPages.StandardController controller) {
      
    }
   
   Public List<WrapperClassEx> getwrapperObj(){
      List<Account> accList = [Select id,name from account limit 5];
      WrapperList = New List<WrapperClassEx>();
      for(Account acc: accList){
        WrapperList.add(New WrapperClassEx(acc,false)); 
      }
      return WrapperList;
   } 
  
   Public Class WrapperClassEx{
     Public Account accObj{get;set;}
     Public Boolean checkBox{get;set;}
    
     Public WrapperClassEx(Account accRec, boolean SelectBox){
        accObj = accRec;
        checkBox = SelectBox;
     }
   }
}

Understand Wrapper class scenarios in salesforce

Wrapper class has many use cases and almost ever developer starts using wrapper class from beginning. Lets see some scenarios where you would need to use wrapper class for building the visualforce functionalities. We know that a location in apex can store only data of one type and when you have data from multiple types then you wont be club them together without a self defined container called as wrapper class.


  • Build a table consisting of rows that have data of different primitive types like integer, string etc
  • Display one object data along with a column to select each rows (a checkbox)
  • One object records with some pictorial depiction column like a colored status bar or anything that isn't part of that object
  • A table consisting of rows that have data from 2 or more objects. For example a row that displays some data from account in addition to data from its associated contact
  • A nested wrapper class that is a wrapper consisting of another class variables.


Using Nested wrapper class in salesforce




public class nestedwrapperclass {
   Public list<firstwarpperclass> fwClassList{get;set;}
   public list<secondNestedWrapClass> sNWrappeclassList{get;set;}
   
    public nestedwrapperclass(ApexPages.StandardController controller) {
      /* build records for first wrapper class list */
        firstwarpperclass fwc1 = new firstwarpperclass('cf-04214','91');
        firstwarpperclass fwc2 = new firstwarpperclass('cf-04215','92');
        firstwarpperclass fwc3 = new firstwarpperclass('cf-04216','93');
        firstwarpperclass fwc4 = new firstwarpperclass('cf-04217','94');
        fwClassList = new list<firstwarpperclass>();
        fwClassList.add(fwc1);
        fwClassList.add(fwc2);  
        
        /* building data for nested wrapper class list*/
        secondNestedWrapClass sNwc1 = new secondNestedWrapClass(fwc1,'NW-00001');
        secondNestedWrapClass sNwc2 = new secondNestedWrapClass(fwc2,'NW-00002');
        secondNestedWrapClass sNwc3 = new secondNestedWrapClass(fwc3,'NW-00003');
        secondNestedWrapClass sNwc4 = new secondNestedWrapClass(fwc4,'NW-00004');
        sNWrappeclassList = new list<secondNestedWrapClass>();
        sNWrappeclassList.add(sNwc1);
        sNWrappeclassList.add(sNwc2);
        sNWrappeclassList.add(sNwc3);
        sNWrappeclassList.add(sNwc4);
         
    }
    
    public class firstwarpperclass{
      public string uniqueId{get;set;}
      public string extesnionScore{get;set;}
      
      public firstwarpperclass(string uId, string exScore){
         uniqueId = uId;
         extesnionScore = exScore;
      }
    }
    /* this is the wrapper class that is nested, that is its one component is another wrapper class variable */
    public class secondNestedWrapClass{
      Public firstwarpperclass fwc{get;set;}
      public string wrappNestedSR{get;set;} 
       
      public secondNestedWrapClass(firstwarpperclass fwcInput,string SRInput){
         fwc = fwcInput;
         wrappNestedSR = SRInput;
      }
    }
}

<apex:page standardController="account" extensions="nestedwrapperclass">
  <apex:form >
     <apex:pageBlock >
        <apex:pageBlockTable value="{!sNWrappeclassList}" var="nw">
           <apex:column value="{!nw.wrappNestedSR}" headerValue="SR Number"/>
           <apex:column value="{!nw.fwc.uniqueId}" headerValue="Unique Id"/>
           <apex:column value="{!nw.fwc.extesnionScore}" headerValue="Extenssion Score"/>
        </apex:pageBlockTable>
     </apex:pageBlock>
  </apex:form>
</apex:page> 

Wrapper class to display records from 2 or more objects in a table











public class acc_ConController {
 Public list<accountNContactData> accConwrapperList{get;set;}
    public acc_ConController(ApexPages.StandardController controller) {
       this.accConwrapperList = new List<accountNContactData>();
       account acc = [select name,id from account limit 1];
       contact con = [select name,id,email from contact where accountid =: acc.id and email != null limit 1];
       accountNContactData acCon = new accountNContactData(acc,con);
       accConwrapperList.add(acCon);
    }
    
    Public class accountNContactData{
      Public Account account{get;set;}
      Public Contact contact{get;set;}
      public accountNContactData(account accinput, contact coninput){
         account = accinput;
         contact = coninput;
      }
    }

}

<apex:page standardController="Account" extensions="acc_ConController">
  <apex:form >
    <apex:pageBlock >
       <apex:pageBlockTable value="{!accConwrapperList}" var="acCon">
          <apex:column value="{!acCon.account.Name}"/>
          <apex:column value="{!acCon.contact.Name}" headervalue="Primary Contact Name"/>
          <apex:column value="{!acCon.contact.Email}" headervalue="Primary Contact Email"/>
       </apex:pageBlockTable>
    </apex:pageBlock>
  </apex:form>
</apex:page>


How to sort wrapper class columns

For sorting primitive data types like integer or string salesforce has built in functionality but to sort custom or developer defined classes like wrapper classes there is no function or method provided by salesforce. 

To sort wrapper class variables we can make use of comparable interface provided by salesforce. 
This was introduced during summer 2012 release. Here is a nice post 
related to how we can use comparable interface to sort wrapper class columns. 

pagination for a wrapper class built table

Almost every time you build a table in visualforce, you are asked to put buttons that help navigate through the table in a better way (that is pagination). The best way to implement pagination is through standard controller but this only supports list of sobject or soql as parameters. 

And thus a table built using wrapper class cannot have pagination using standard controller even if one part of the row consists of sobject data. We can use custom iterator for building pagination for wrapper class table. Use hasNext, next iterators for building the custom pagination logic.

Covering wrapper class in a test class




lets see how we can cover a wrapper class in a test class. Below test class cover our wrapper class controller for nested wrapper class example. 

So as to call the wrapper class we need to instantiate the class using the outer class name like, nestedwrapperclass.secondNestedWrapClass and pass the parameters in the constructor. 

If the wrapper class is getting called from a constructor or different method then you can simply call that method or instantiate the outer class that should automatically call the wrapper class and increase the coverage for your wrapper class. In below example i have specially called each of the 2 wrapper classes just to demo else i could i simply called the constructor of main class to cover both wrapper classes.



@isTest(seealldata=true)
public class nestedwrapperclass_Test{
    
    static testMethod void wrappertestmethod1() {
       Test.startTest();
       account acc = new account(name = 'testname');
       insert acc;
       ApexPages.StandardController sc = new ApexPages.StandardController(acc);
        //nestedwrapperclass nw = new nestedwrapperclass(sc);
        nestedwrapperclass.firstwarpperclass nWclss = new nestedwrapperclass.firstwarpperclass('tstuid','88');
        
       nestedwrapperclass.secondNestedWrapClass nWclss2 = new nestedwrapperclass.secondNestedWrapClass(nWclss,'NS-00001');
       
       Test.stopTest(); 
       
    }
         



Article 1** Article 2** Article 3** Article 4** Article 5** Article 6** Article 7** Article 8** Article 9 ** Article 10

Click For : Salesforce Interview Question And Answers

15 comments:

  1. Very nice! can think of many uses for this pattern.

    ReplyDelete
  2. Superb Explanation, Great work yar...

    ReplyDelete
  3. Really nice and easily understandable explanation
    Thank you so much for posting this.. :-)

    ReplyDelete
  4. Well explained!!!!! Hats off !!!!! You have a great future in salesforce!!!!!

    ReplyDelete
  5. Really impressed Yoganand!!!! Yes, you have a bright future!!!!! keep it up!!!!

    ReplyDelete
  6. Hello Sir, the output of the above code is just displaying the records.. can we use some custom button to save them in a separate list or something??

    ReplyDelete
  7. Nice explanation of wrapper clas, with just few lines of code.

    ReplyDelete
  8. Really Nice Post, wonderful explanation of wrapper class with few lines of code

    ReplyDelete
  9. super way of teaching.but in this if we want that on clicking the checkbox the detail of that contact is display then what will be the code plzzz send this

    ReplyDelete
  10. thanks sir but if we want that on clicking the checkbox the detail of that particular accont isdisplay then what will be the code

    ReplyDelete
  11. well explained

    ReplyDelete
  12. This is best explanation for wrapper class so far I have seen, thanks man....

    ReplyDelete
  13. Wrapper class output is not to expected as per interviewers in 2017.
    Any chances of updating ??

    ReplyDelete