Find your content:

Search form

You are here

How to improve the functionality of my OppContactRole VF page


I'd like to be able to add / edit Opp. Contact Roles directly from the Opp. view page.

So far I have created a VF page to render the Opp. detail page and a table to allow the updating of the related OppContactRoles.

I have two questions: 1. What would be the best way to add a 'New' button. When clicked, this button would add a new, blank row to the table allowing a new OppContactRole to be added. 2. What is the best way to ensure that only one OppContactRole is set as the primary?

Here is my code:

<apex:page standardController="Opportunity" extensions="OppExtension">
<apex:detail relatedList="false" inlineEdit="true"/>
<apex:form >
    <apex:pageBlock title="Opportunity Contacts">
        <apex:pageBlockButtons >
            <apex:commandButton action="{!quicksave}" value="Save"/>
            <apex:commandButton action="{!cancel}" value="Cancel"/>
        <apex:pageBlockTable value="{!opportunity.opportunitycontactroles}" var="item">
            <apex:column title="First Name">
                <apex:inputField value="{!}"/>
            <apex:column title="Last Name">
                <apex:inputField value="{!}"/>
            <apex:column title="Role">
                <apex:inputField value="{!item.role}"/>
            <apex:column title="Primary Contact?">
                <apex:inputField value="{!item.isprimary}"/>


public class OppExtension {
    private final Opportunity opp;

    public OppExtension (ApexPages.StandardController controller) {
        this.opp = (Opportunity)controller.getRecord();

Also I'm not sure if allowing the users to directly edit the fields is good practice. Thoughts?


Attribution to: Davin Casey

Possible Suggestion/Solution #1

You're probably best using a Wrapper class for the OpportunityContactRole, with a boolean checked field which allows you to select the OCR as Primary.

You can then bind to this list of OpportunityContactRoleWrapper, which will need to contain instances of the OpportunityContactRoleWrapper to render on the page..

To add a new record, on click of the add button, you will need to create a new OpportunityContactRoleWrapper in the controller and then add it to the list, this will then render the additional row on the page.

To allow only record being Primary, have a bit of javascript, which allows only one of the checkboxes to be checked and automatically unchecks a previously checked checkbox.

Attribution to: techtrekker

Possible Suggestion/Solution #2

I would try it with two apex methods and some visualforce code:

UPDATE: i've updated the code so you can use it now.

Apex Class:

public with sharing class test2 {

    public List<OpportunityContactRole> objectsToInsert { get; set; } 
    public Integer numberOfRowToRemove { get; set; }
    public Opportunity opp { get; set; }

    public test2()
        objectsToInsert = new List<OpportunityContactRole>();
        opp = [ Select Id From Opportunity Limit 1 ];

    // The method to add a new item to the list
    public PageReference addNewObject(){

        OpportunityContactRole newObject = new OpportunityContactRole(OpportunityId =;

        return null;

    // The method to remove an item from the list
    public PageReference removeNewObject(){


        return null;

And Visualforce Page:

<apex:page controller="test2">

<apex:variable value="{!0}" var="rowNumber" />

<!-- A main button to add a new item -->
<apex:commandButton value="Add" action="{!addNewObject}" reRender="newItems,panelWithVar" immediate="true"/>

<!-- Here we will use an extra variable to define a row number -->
<apex:outputPanel id="panelWithVar">
    <apex:variable value="{!0}" var="rowNumber" />

<!-- A list with new items -->
<apex:pageBlockTable value="{!objectsToInsert}" var="item" id="newItems">
    <!-- A button to remove individual entry. 
         We must to pass the line number to define a list entry number to remove -->
    <apex:column width="5%">
        <apex:commandButton action="{!removeNewObject}" value=" X " reRender="newItems,panelWithVar">
            <apex:param name="p1" value="{!rowNumber}" assignTo="{!numberOfRowToRemove}"/>

    <!-- Moreover here we incrementing the row number variable -->
    <apex:column headerValue="{!$ObjectType.OpportunityContactRole.fields.Role.label}">
        <apex:inputField value="{!item.Role}"/>
        <apex:variable var="rowNumber" value="{!rowNumber + 1}" />




Attribution to: Sergej Utko
This content is remixed from stackoverflow or stackexchange. Please visit

My Block Status

My Block Content