+ Start a Discussion
Jack InsJack Ins 

VF Page Account Contact Role on Contact Standard Page Layout

Hi Everyone,

 

I am trying to build a VF Page that will sit in a standard Contact Page Layout.  I know that Account Contact Role relates to Account and there is a related list on Accounts.  What we are looking for is a way to show these Account Contact Roles on the Contact.

 

My best assumption is to create a VF Page that can be added to the standard page layout with a apex class related to the Account Contact Role where the ContactId from the AccountContactRole object is equal to the current Contact Id.

 

The following code is my VF page and Apex Class.  I feel there may already be a solution for this so I am totally open to new suggestions or fixes to my current code and logic.


Thank You Very Much.

 

<apex:page standardcontroller="Contact" recordSetVar="contacts" extensions="AccountContactRoles">
 <apex:pageBlock title="Account Contact Roles">
        <apex:form id="theForm1">
            <apex:pageBlockSection >
                <apex:dataList value="{!AccountContactRoles}" var="acr" type="1">
                    {!acr.Id}
                </apex:dataList>
            </apex:pageBlockSection>
            <apex:panelGrid columns="2">
                <apex:commandLink action="{!previous}">Previous</apex:commandlink>
                <apex:commandLink action="{!next}">Next</apex:commandlink>
            </apex:panelGrid>
        </apex:form> 
    </apex:pageBlock>
</apex:page>

 This is my VF Page Coding

 

public with sharing class AccountContactRoles {
	private final Contact acr;
	public Id cntId{get;set;}
	
	public AccountContactRoles(ApexPages.StandardSetController controller){
		this.acr = (Contact)controller.getRecord();
	}
	public ApexPages.Standardsetcontroller acrRecords{
		get{
			if(acrRecords == null){
				cntId = ApexPages.currentPage().getParameters().get('Id');
				acrRecords = new ApexPages.Standardsetcontroller(
				Database.getQueryLocator([Select Id, AccountId, ContactId, Role, IsPrimary From AccountContactRole 
				Where ContactId=:cntId]));
			}
			return acrRecords;
		}
		private set;
	}
	public List<AccountContactRole> getAccountContactRoles(){
		return (List<AccountContactRole>) acrRecords.getRecords();
	}
}

 This is my Apex Class.

Best Answer chosen by Admin (Salesforce Developers) 
JHayes SDJHayes SD

Assuming you don't need paging, you can assign a List of AccountContactRole objects to a property in your Apex class.  The following worked for me:

 

Apex class:

 

public with sharing class AccountContactRoles {
    private final Contact acr;
    
    public AccountContactRoles(ApexPages.StandardController controller){
        this.acr = (Contact)controller.getRecord();
    }
    
    public List<AccountContactRole> acrs {
        get {
            if (acrs == null) {
                acrs = [Select Id, AccountId, ContactId, Role, IsPrimary From AccountContactRole 
                    Where ContactId=:acr.Id];                
            }
            return acrs;
        }
        private set;
    }
}

 

 

Visualforce page:

 

<apex:page standardcontroller="Contact" extensions="AccountContactRoles">
 <apex:pageBlock title="Account Contact Roles">
        <apex:form id="theForm1">
            <apex:pageBlockSection >
                <apex:dataList value="{!acrs}" var="acr" type="1">
                    {!acr.Id}
                </apex:dataList>
            </apex:pageBlockSection>
        </apex:form> 
    </apex:pageBlock>
</apex:page>

 You can insert your Visualforce page into the Contact layout via the layout editor in the UI.

 

Regards, 

Jeremy

All Answers

JHayes SDJHayes SD

Assuming you don't need paging, you can assign a List of AccountContactRole objects to a property in your Apex class.  The following worked for me:

 

Apex class:

 

public with sharing class AccountContactRoles {
    private final Contact acr;
    
    public AccountContactRoles(ApexPages.StandardController controller){
        this.acr = (Contact)controller.getRecord();
    }
    
    public List<AccountContactRole> acrs {
        get {
            if (acrs == null) {
                acrs = [Select Id, AccountId, ContactId, Role, IsPrimary From AccountContactRole 
                    Where ContactId=:acr.Id];                
            }
            return acrs;
        }
        private set;
    }
}

 

 

Visualforce page:

 

<apex:page standardcontroller="Contact" extensions="AccountContactRoles">
 <apex:pageBlock title="Account Contact Roles">
        <apex:form id="theForm1">
            <apex:pageBlockSection >
                <apex:dataList value="{!acrs}" var="acr" type="1">
                    {!acr.Id}
                </apex:dataList>
            </apex:pageBlockSection>
        </apex:form> 
    </apex:pageBlock>
</apex:page>

 You can insert your Visualforce page into the Contact layout via the layout editor in the UI.

 

Regards, 

Jeremy

This was selected as the best answer
Jack InsJack Ins

This worked great.  Thank you.

Could I ask for your help with my test class?  My code is below but I can't get it to cover my class.

@isTest
//Created by Dwayne Branthoover 04/03/2013

class TestContactRole{
	static testMethod void myUnitTest(){
		Test.startTest();
		//We run our unit test as this user
        User testSysAdminUser = new User(alias = 'standt', email='standarduser@testorg.com', 
            emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US', 
            localesidkey='en_US', profileId = [select id from profile where name='System Administrator' LIMIT 1].Id, 
            timezonesidkey='America/New_York', username='ASstandarduser@testorg.com');
            
        insert testSysAdminUser;
        
        System.runAs(testSysAdminUser)
        {
        	//Creates a Master Agent record
        	Account acctMaster = new Account(Name = 'acctMaster');
	        	acctMaster.RecordTypeId = '01240000000Hqtc';
    		insert acctMaster;
    		//Creates 2 sub-producer records to test various fee's.
    		Account acctExisting1 = new Account(Name = 'acctTester1');
	        	acctExisting1.RecordTypeId = '01240000000Hqth';
	        	acctExisting1.NB_Fee__c =1;
	        	acctExisting1.PLWP_PYE__c = 100.00;
    		insert acctExisting1;
    		Account acctExisting2 = new Account(Name = 'acctTester2');
	        	acctExisting2.RecordTypeId = '01240000000Hqth';
	        	acctExisting2.NB_Fee__c =1.5;
	        	acctExisting2.PLWP_PYE__c = 200.00;
    		insert acctExisting2;
    		//Creates a Contact to work with.
    		Contact cntTest = new Contact(FirstName = 'Test');
    			cntTest.LastName = 'Contact';
    			cntTest.Email = 'test@hanover.com';
    			cntTest.RecordTypeId = '01240000000DVfV';
			insert cntTest;
    		//Create the Account Contact Role records.
    		AccountContactRole acr1 = new AccountContactRole(AccountId = acctMaster.Id);
    			acr1.ContactId = cntTest.Id;
    			acr1.Role = 'Test 1';
			insert acr1;
			AccountContactRole acr2 = new AccountContactRole(AccountId = acctExisting1.Id);
    			acr2.ContactId = cntTest.Id;
    			acr2.Role = 'Test 2';
			insert acr2;
			AccountContactRole acr3 = new AccountContactRole(AccountId = acctExisting2.Id);
    			acr3.ContactId = cntTest.Id;
    			acr3.Role = 'Test 3';
			insert acr3;
			
			//List AccountContactRoles for the contact.
			List<AccountContactRole> acrsList = new List<AccountContactRole>();
	        try {
	        	AccountContactRole acr = [Select Id, Account.ShippingState, Account.Name, Account.Agent_Code__c, 
	                	Account.RecordType.Name, Role, IsPrimary 
	                	From AccountContactRole 
	                    Where ContactId=:cntTest.Id 
	                    Order By Account.RecordType.Name, Account.Agent_Code__c, Role];      
                acrsList.add(acr);
                }
                catch (Exception e){System.debug('AccountContactRole Record Does Not Exist.');}
	    }
	    Test.stopTest();
    }
}

 

JHayes SDJHayes SD

Glad it worked out!  Check out the following document:  http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

 

Specifically, go to the section titled 'Test Methods and Visualforce Controllers'.  You need to use the ApexPages class to create an instance of the page, which will in turn cover you for the controller.

 

Regards, jh

Jack InsJack Ins

Thank you.  By the way, here is a copy of the final code for the page and class.

 

<apex:page standardcontroller="Contact" extensions="AccountContactRoles">
	<apex:outputPanel >
	<apex:form >
		<apex:pageBlock >
			<apex:pageBlockSection columns="1"> 
				<apex:dataTable value="{!acrs}" var="acr" id="acrTable" rules="all" cellpadding="5px">
					<apex:column style="text-align:center;" width="100px" headerValue="Primary Contact">
                 		<apex:outputField value="{!acr.IsPrimary}"/>
                 	</apex:column>
                 	<apex:column width="150px" headerValue="Contact Role">
                 		<apex:outputText value="{!acr.Role}"/>
                 	</apex:column>
					<apex:column width="150px" headerValue="Agent Type">
                    	<apex:outputText value="{!acr.Account.RecordType.Name}"/>
                   	</apex:column>
                 	<apex:column style="text-align:right;" width="100px" headerValue="Agent Code">
                 		<apex:outputText value="{!acr.Account.Agent_Code__c}"/>
                 	</apex:column>
                 	<apex:column width="300px" headerValue="Agent Name">
                 		<apex:outputLink value="/{!acr.Account.Id}" target="_parent">{!acr.Account.Name}</apex:outputLink>
                 	</apex:column>
                 	<apex:column style="text-align:center;" width="125px" headerValue="Agent State">
                 		<apex:outputText value="{!acr.Account.BillingState}"/>
                 	</apex:column>
				</apex:dataTable> 
			</apex:pageBlockSection>
		</apex:pageBlock> 
	</apex:form>
	</apex:outputPanel>
</apex:page>


Apex Class......
public with sharing class AccountContactRoles {
    private final Contact acr;
    
    public AccountContactRoles(ApexPages.StandardController controller){
        this.acr = (Contact)controller.getRecord();
    }
    
    public List<AccountContactRole> acrs {
        get {
            if (acrs == null) {
                acrs = [Select Id, Account.BillingState, Account.Name, Account.Agent_Code__c, 
                	Account.RecordType.Name, Role, IsPrimary 
                	From AccountContactRole 
                    Where ContactId=:acr.Id 
                    Order By Account.RecordType.Name, Account.Agent_Code__c, Role];                
            }
            return acrs;
        }
        private set;
    }
}

 

davidjgriffdavidjgriff

If you are just displaying AccountContactRoles on the Contact page, you actually don't need any Apex at all. You can do it all with straight Visualforce.

 

Here's a pretty similar page that I have used in the past.

 

<apex:page standardController="Contact">
    
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript">
        
//remove the hovers and retarget the links to the parent window.
        $(document).ready(function(){
          $('a').attr('target', '_parent');
          $('a').attr('onmouseover', '');
        });
        
    </script>
    <apex:pageBlock mode="maindetail">
    
        <apex:pageBlockSection columns="1">
        
            <apex:pageBlockTable value="{!Contact.AccountContactRoles}" var="acr">
            
                <apex:column value="{!acr.AccountId}"/>
                <apex:column value="{!acr.Role}"/>
                <apex:column value="{!acr.IsPrimary}"/>
                <apex:column value="{!acr.Account.Type}"/>
                <apex:column value="{!acr.Account.OwnerId}"/>
            
            </apex:pageBlockTable>
        
        </apex:pageBlockSection>
    
    </apex:pageBlock>

 

Jack InsJack Ins

David,

I really like the idea of not having a class, my only problems is ordering the results.  I will need to place an order to the records or even better have the ability to sort the columns.  From everything that I have read I would need to have a class to make either happen.

Thoughts????

Thanks Dwayne

davidjgriffdavidjgriff

Depending on your comfort level with javascript or jQuery, you could just sort the table on the client side. I don't this will be a very large list, yes?

Jack InsJack Ins

Possibility of up to 50 or so records.  Our contacts can traverse multiple accounts giving them the ability to have many account contact roles.