Salesforce Wrapper Class Example

A quick search for Salesforce wrapper results in the following definition. A wrapper or container class is a class, a data structure, or an abstract data type whose instances are collections of other objects.

That's fine but if you're new to the concept then it is likely that the definition of a Salesforce wrapper class is not as useful as a practical example of the logic.

Let's say that you want to build a simple Visualforce page that will display a list of Contacts. For the page you will require a controller similar to the following:

/*
	Created by: Greg Hacic
	Last Update: 22 January 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
*/
public with sharing class simpleController {
	
	public List<Contact> contacts = new List<Contact>(); //list for holding the Contact records to be displayed on the page
	
	//contructor for the page
	public simpleController() {
		for (Contact c : [SELECT Account.Name, Email, FirstName, Id, LastName, Phone FROM Contact ORDER BY LastName LIMIT 100]) { //start looping through a bunch of Contact records
			contacts.add(c); //add the record to our list
		}
	}
	
	//allows for Visualforce page to request the list of Contacts
	public List<Contact> getContacts() {
		return contacts; //return the list of Contact records
	}
}

The Visualforce page corresponding to the above controller looks like:

<apex:page controller="simpleController">
<!--
	Created by: Greg Hacic
	Last Update: 22 January 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
-->
	<apex:pageBlock mode="maindetail" title="Simple List of Contacts">
		<apex:pageBlockTable value="{!contacts}" var="c">
			<apex:column value="{!c.FirstName}"></apex:column>
			<apex:column value="{!c.LastName}"></apex:column>
			<apex:column value="{!c.Account.Name}"></apex:column>
			<apex:column value="{!c.Email}"></apex:column>
			<apex:column value="{!c.Phone}"></apex:column>
			<apex:column value="{!c.Id}"></apex:column>
		</apex:pageBlockTable>
	</apex:pageBlock>
</apex:page>

The resulting page looks like:

Now let's say that you want to add another column to the resulting page with an integer that corresponds to the row number for the record. This would be a great use for a Salesforce wrapper class.

Basically, we are looking to combine two different objects into one list within the page controller so that we can iterate over that list in the Visualforce page. In this case the two objects are a Contact object and an Integer. Altering our original controller to allow for the wrapper class results in the following controller.

/*
	Created by: Greg Hacic
	Last Update: 22 January 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- controller that wraps a Contact record with an Integer and returns the list of wrapped objects
*/
public with sharing class simpleController {
	
	public List<contactWrapper> wrappedObjects = new List<contactWrapper>(); //list for holding the wrapped Contacts and Integers to be displayed on the page
	
	//contructor for the page
	public simpleController() {
		Integer i = 0; //integer for tracking the row counter value we want to pass back in the wrapper
		for (Contact c : [SELECT Account.Name, Email, FirstName, Id, LastName, Phone FROM Contact ORDER BY LastName LIMIT 100]) { //start looping through a bunch of Contact records
			i++; //increment the integer
			contactWrapper wrappedObject = new contactWrapper(c, i); //wrap the Contact with the Integer, which calls the contactWrapper class below
			wrappedObjects.add(wrappedObject); //add the wrapper object to our list
		}
	}
	
	//allows for Visualforce page to request the list of contactWrapper records
	public List<contactWrapper> getWrappedObjects() {
		return wrappedObjects; //return the list of contactWrapper records
	}
	
	//wrapper class definition
	public class contactWrapper {
		
		public Contact contact {get; set;} //Contact object
		public Integer rowCounter {get; set;} //row Integer
		
		//constructor for wrapper
		public contactWrapper(Contact passedContact, Integer passedInteger) {
			contact = passedContact; //assign Contact
			rowCounter = passedInteger; //assign row counter
        }
    }

}

To make use of that new wrapper being passed from the controller we need to modify our Visualforce page as follows.

<apex:page controller="simpleController">
<!--
	Created by: Greg Hacic
	Last Update: 22 January 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
-->
	<apex:pageBlock mode="maindetail" title="Wrapped List of Contacts & Integers">
		<apex:pageBlockTable value="{!wrappedObjects}" var="w">
			<apex:column value="{!w.rowCounter}">
				<apex:facet name="header">#</apex:facet>
			</apex:column>
			<apex:column value="{!w.contact.FirstName}"></apex:column>
			<apex:column value="{!w.contact.LastName}"></apex:column>
			<apex:column value="{!w.contact.Account.Name}"></apex:column>
			<apex:column value="{!w.contact.Email}"></apex:column>
			<apex:column value="{!w.contact.Phone}"></apex:column>
			<apex:column value="{!w.contact.Id}"></apex:column>
		</apex:pageBlockTable>
	</apex:pageBlock>
</apex:page>

Notice that we now have to use dot notation for accessing the details of the Contact record as we iterate over the list of wrapped data. Since we assign the wrapped data to the variable "w" we have to tell the page which object from that object that we want for each column. Our options as defined within the controller are the "contact" object, which holds the Contact fields from our SOQL query, and the "rowCounter" object, which is simply an Integer.

You will also notice that we need to define the column header for the "rowCounter" object from the wrapper using the <apex:facet> tag. Otherwise the column header will be blank.

The resulting visualforce page looks as follows:

Automated Exchange Rates in Salesforce.com

Reduce Repetitive Tasks, Eliminate Errors & Free Up Your Administrators.

Birthday Reminders for Salesforce.com

It might lead to a sale. Or it might make you feel good.