Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

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:pageBlockButtons>    
        <apex:pageBlockTable value="{!opportunity.opportunitycontactroles}" var="item">
            <apex:column title="First Name">
                <apex:inputField value="{!item.contact.firstname}"/>
            </apex:column>
            <apex:column title="Last Name">
                <apex:inputField value="{!item.contact.lastname}"/>
            </apex:column>
            <apex:column title="Role">
                <apex:inputField value="{!item.role}"/>
            </apex:column>
            <apex:column title="Primary Contact?">
                <apex:inputField value="{!item.isprimary}"/>
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:form>

Extension:

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 contact.name fields is good practice. Thoughts?

Thanks.

share|improve this question
    
Is there a specific requirement where you cannot utilize the OOB Opportunity Edit page? Otherwise, I would suggest using the OOB functionality as much as possible. –  James Loghry Dec 10 '12 at 17:37
    
I think Salesforce will simply ignore (silently fix the data) even if you'll mark them all as primary :) Try it with some mass insert/update for example, that'd mean one less thing to worry about. –  eyescream Dec 10 '12 at 20:33
    
@DancinLlama The specific use case here is that there are validation rules in place ensuring that there is always a primary OppContact. However if a user edits an Opportunity, enters a lot of new information then Saves, they are prevented from doing so, as expected. Opening a second tab etc. is not a desirable workaround so there is the need to be able to edit the OppContactRoles directly from the Opp edit page. –  DavinC Dec 11 '12 at 8:35
    
@DavinC You can add Opportunity Contact Roles from the Edit screen if you click on edit of a Opportunity (right from the related list) Using standard func, you can also set the Primary role from there. If it's just a Validation Rule issue, why not modify the rule itself or add some workflow around the Opportunity instead of creating a custom VF page and Apex Code? –  James Loghry Dec 11 '12 at 19:11
    
@DancinLlama they're happy with the validation rule as it ensures there is always a primary contact. Not sure what you mean with the Edit from related list suggestion. Basically I need to be able to edit (and add/remove) opportunity contacts from the opportunity edit page - not the opportunity contact role edit page. –  DavinC Dec 12 '12 at 11:07

2 Answers 2

up vote 2 down vote accepted

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 = opp.id);
        objectsToInsert.add(newObject);

        return null;
    }

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

        objectsToInsert.remove(numberOfRowToRemove);  

        return null;
    }
}

And Visualforce Page:

<apex:page controller="test2">
<apex:form>

<apex:pageBlock>
<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" />
</apex:outputPanel>

<!-- 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}"/>
        </apex:commandButton>
    </apex:column>

    <!-- 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}" />
    </apex:column>

</apex:pageBlockTable>

</apex:pageBlock>

</apex:form>
</apex:page>
share|improve this answer
    
Thanks for the help. Unable to save that class: Save error: Method does not exist or incorrect signature: extraServices.remove(Integer). Any suggestions? –  DavinC Dec 12 '12 at 12:26
1  
I've updated the code –  mast0r Dec 12 '12 at 12:52

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.