Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
in Salesforce by (11.9k points)

The company recently came upon the need to create a side by side record comparison in Visualforce / Apex. We routinely have the need to merge leads into contacts. Previously this was handled in S-Controls; however, recent initiatives and desire to have support for our code on into the future has pushed us to move many of our S-Controls into Visualforce pages and Apex code.

We are looking to achieve something like this:enter image description here

I have experimented somewhat (with little luck) doing this using the apex:pageBlockTable tag; however, I am not sure how to get two sets of data to render through when it is expecting a single SObject.

All of the prior code I have to work with was done in S-Controls using JavaScript; and while this code does work now - we need to port this to a VisualForce page. Obviously I can manually write this using HTML tables...etc but I believe that defeats the purpose of using the stock Salesforce functionality.

I'm definitely open to alternative methods - as the one i have outlined works, but requires an almost painful amount of coding to make it viable (especially as fields are updated/removed/added in the future).

1 Answer

0 votes
by (32.1k points)
edited by

In order to create a side-by-side comparison in VisualForce, you need to do the following edits:

So, first of all, apex:pageBlockTable  can be used ti handle any kind of object which is passed into the value  parameter. 

Secondly, you'd need a wrapper class to encapsulate two records at the same time as follows:

public with sharing class LeadContactCompareWrapper {

    public static final String SALUTATION = 'Salutation';

    public static final String FIRST_NAME = 'First Name';

    public static final String LAST_NAME = 'Last Name';

    public static final String EMAIL = 'Email';

    public static final String PHONE = 'Phone';

    public static final String STREET = 'Street';

    public static final String CITY = 'City';

    public static final String STATE = 'State';

    public static final String COUNTRY = 'Country'; 

    public static final String ZIP_POSTAL = 'Zip / Postal Code';

    public static final String TITLE = 'Title';

    public static final String PRIMARY_FUNCTIONAL_ROLE = 'Primary Functional Role';

    public static final String SECONDARY_FUNCTIONAL_ROLE = 'Secondary Functional Role';

    public static final String BULLETIN = 'Bulletin'; 

    public static final String CREDIT_MEMO = 'Credit Memo';

    public static final String FS_INSIGHTS = 'FS Insights';

    public static final String MANUFAC_IND_INSIGHTS = 'Manufact. Ind Insights';

    public static final String LIT_AND_FRAUD = 'Lit. & Fraud News';

    public static final String REGULATORY_INSIGHTS = 'Regulatory Insights';

    private Lead lead; 

    private Contact contact; 

    public List<Compare> information { get; set; }

    public List<Compare> marketing { get; set; }

    public List<Compare> furtherDetails { get; set; }

    public List<SelectOption> names { get;set; }

    public String newName { get;set; }

    public Id getContactId() { 



    public Id getAccountId() { 



    public Id getLeadId() { 

        return this.lead.Id;


    public Lead getLead() { 

        return this.lead;


    public Contact getContact() { 



    public LeadContactCompareWrapper(Lead lead, Contact contact) { 

        this.lead = [Select Id, DeliveryPreference__c, ACE__c,AML__c,BusContinuity__c,CorpGovSOX__c,ERM__c,FinancialRisk__c,InternalAudit__c,ITAsset__c,ITAudit__c,ITSecurity__c,LitSupport__c,ORM__c,SelfAssessment__c,SpendRisk__c, Owner.Name, Company, Bulletin__c,Credit_Memo__c,FSInsights__c,Manufact_Ind_Insights__c,LitFraudNews__c,RegulatoryInsights__c, LastModifiedDate, Salutation, FirstName, LastName, Email, Phone, Street, City, State, Country, PostalCode, Title, Primary_Functional_Role__c, SecondaryFunctionalRole__c From Lead Where Id = :lead.Id]; = [Select Id, Owner.Name, Account.Id, Account.Name, Bulletin__c,Credit_Memo__c,FSInsights__c,Manufact_Ind_Insights__c,LitFraudNews__c,RegulatoryInsights__c,  LastModifiedDate, Salutation, FirstName, LastName, Email, Phone, MailingStreet, MailingCity, MailingState, MailingCountry, MailingPostalCode, Title, Primary_Functional_Role__c, SecondaryFunctionalRole__c From Contact Where Id = :contact.Id];



    private void init() { 

        this.information = new List<Compare>(); = new List<Compare>();

        this.furtherDetails = new List<Compare>();

        // this part will suck but it has to be done


                        (this.lead.Salutation != null) ? this.lead.Salutation : '', 

                        ( != null) ? : ''


        /* Continue adding as many compare fields for the 'information' section as needed... */

        // Marking Subscriptions


                        (this.lead.Bulletin__c != null) ? this.lead.Bulletin__c : '', 

                        ( != null) ? : ''


        /* Continue adding as many compare fields for the 'marketing' section as needed... */                       

        // Further information - just for display purposes


                        (this.lead.Owner.Name != null) ? this.lead.Owner.Name : '', 

                        ( != null) ? : '',




        /* Continue adding as many compare fields for the 'further information' section as needed... */                     



     * Creates a comparison object


    private Compare createCompare(string label, String val1, String val2, Boolean isVal1, Boolean isVal2) { 

        Compare c = new Compare(label);

        c.selectVal1 = isVal1;

        c.selectVal2 = isVal2;

        c.val1 = val1;

        c.val2 = val2;

        return c;



     * Defaults our comparison to value 1 as selected


    private Compare createCompare(String label, String val1, String val2) {

        return createCompare(label, val1, val2, true, false);



Also, you need to create a 'compare' class whihc holds two values along with two booleans  which are based on the value is selected:

public class Compare { 

    public Compare (String label) { 

    this.label = label;


    public String label { get; set; }

    public Boolean selectVal1 { get; set; }

    public Boolean selectVal2 { get; set; }

    public String val1 { get; set; }

    public String val2 { get; set; }


Now, you'd need to put all of this on a VF page as follows:

<apex:pageblocktable value="{!leadToContact.information}" var="compare">


        <apex:facet name="header">Information</apex:facet>




        <apex:facet name="header">Lead</apex:facet>

        <apex:inputcheckbox id="val1" label="{!compare.val1}" onclick="uncheckOtherCompare(this);" title="{!compare.val1}" value="{!compare.selectVal1}" />

        <apex:outputlabel value="{!compare.val1}" />



        <apex:facet name="header">Contact</apex:facet>

        <apex:inputcheckbox id="val2" label="{!compare.val2}" onclick="uncheckOtherCompare(this);" value="{!compare.selectVal2}" />

        <apex:outputlabel value="{!compare.val2}" />



Finally, you need a little bit of javascript to make the radio buttons behave properly.

function uncheckOtherCompare(obj) {

    // Get the id of the object being checked

    var objId =;

    if (objId.indexOf('val1') >= 0) {

      objId = objId.replace('val1', 'val2');  

    } else {

      objId = objId.replace('val2', 'val1'); 


    if (obj.checked) {

      document.getElementById(objId).checked = false; 

    } else if (!document.getElementById(objId).checked) {

      // If the user is trying to uncheck both boxes, recheck the box that is being passed in.  

      // We can't have 'no' boxes checked on a given row

      obj.checked = true; 



You can place the javascript anywhere on the page, but it's best to link it or place it at the top of the document right after the opening tag. After that, you can access your  LeadContactCompareWrapper.[information|marking|furtherDetails] array and step through each one to determine the selected values, or write additional helper classes to expedite the process. You'd be able to create a side-by-side record compariosion which allws you to merge your leads directly with your ocntacts.

Do you want to build a career in Salesforce? Enroll in this Salesforce course online training to start your journey!

Browse Categories