0

We use campaigns to build letters that go out annually, and the members of that campaign represent the "main" address and the "CC" contacts. As a result, we have hundreds of campaigns, each with 2-5 members assigned. Managing the order in which the CCs display is a concern of the business.

I was attempting to create a visualforce popup, that displays the CampaignMembers related to campaign, and allow the user to adjust the picklists that drive the CC order. I can get the page to load and display the appropriate inputsFields and outputFields, but the records won't save when the button is clicked. What am I missing?

<apex:page standardController="Campaign">
    <apex:form>
        <apex:pageblock title="{!Campaign.name}">
            <apex:pageBlockSection >
                <apex:outputField value="{!Campaign.name}"/>
                <apex:outputField value="{!Campaign.Type}"/>
            </apex:pageblocksection>
        </apex:pageblock>
    </apex:form>

    <apex:form>
        <apex:pageblock title="Edit Related Members">
            <apex:pageBlocktable value="{!Campaign.CampaignMembers}" var="cm">
                <apex:column><apex:outputField value="{!cm.name}"/></apex:column>
                <apex:column><apex:outputField value="{!cm.CC_Order__c}"/></apex:column>
                <apex:column><apex:inputField value="{!cm.CC_Order__c}"/></apex:column>
            </apex:pageBlocktable>
            <apex:commandButton action="{!save}" value="Save Changes"/>        
        </apex:pageblock>
    </apex:form>
</apex:page>
1
  • 3
    You are saving the campaign and not the campaign member by using the standard save method. You will need a custom controller or use the standardsetcontroller for campaign member for the page
    – Eric
    Commented Dec 1, 2015 at 19:07

2 Answers 2

3

You can list the campaign members using a StandardSetController, then call its save method:

            <apex:pageBlocktable value="{!campaignMembers.Records}" var="cm">
                <apex:column><apex:outputField value="{!cm.name}"/></apex:column>
                <apex:column><apex:outputField value="{!cm.CC_Order__c}"/></apex:column>
                <apex:column><apex:inputField value="{!cm.CC_Order__c}"/></apex:column>
            </apex:pageBlocktable>

      ...

            <apex:commandButton action="{!campaignMembers.save}" value="Save Changes"/>

You'll need an extension for this:

public class CampaignExtension {
    public ApexPages.StandardSetController campaignMembers { get; set; }
    public CampaignExtension(ApexPages.StandardController controller) {
        campaignMembers = new ApexPages.StandardSetController(
            [SELECT Name, CC_Order__c FROM CampaignMember WHERE CampaignId = :controller.getId()]
        );
    }
1
  • I learned something here. Pretty clever and concise
    – cropredy
    Commented Dec 1, 2015 at 19:52
1

Create an extension, and do your save there. Here is an example:

Modify your page like this :

<apex:page standardController="Campaign" extensions="CampaignExtension">
    <apex:form>
        <apex:pageblock title="{!currentCampaign.name}">
            <apex:pageBlockSection >
                <apex:outputField value="{!currentCampaign.name}"/>
                <apex:outputField value="{!currentCampaign.Type}"/>
            </apex:pageblocksection>
        </apex:pageblock>
    </apex:form>

    <apex:form>
        <apex:pageblock title="Edit Related Members">
            <apex:pageBlocktable value="{!currentCampaign.CampaignMembers}" var="cm">
                <apex:column><apex:outputField value="{!cm.name}"/></apex:column>
                <apex:column><apex:outputField value="{!cm.CC_Order__c}"/></apex:column>
                <apex:column><apex:inputField value="{!cm.CC_Order__c}"/></apex:column>
            </apex:pageBlocktable>
            <apex:commandButton action="{!save}" value="Save Changes"/>        
        </apex:pageblock>
    </apex:form>
</apex:page>

Then create the class below:

public with sharing class CampaignExtension() {
   public Campaign currentCampaign {get;set;}

  public CampaignExtension(ApexPages.StandardController ctr) {
    //If you get an error here, replace it with a SoQL query (Left one commented out below)
    currentCampaign = (Campaign) ctr.getRecord();
    //currentCampaign = [select Id, Name, Type, (select Id, Name, CC_Order__c from CampaignMembers) from Campaign where id = :ctr.getID()];
  }

  public pageReference save() {
     upsert currentCampaign;

     //Being overly verbose here, you could simply update the property.
     List<CampaignMembers> members = currentCampaign.CampaignMembers;
     upsert members;

  }
}

Voila!

1
  • Thank you everyone! I was hoping an extension wasn't necessary, but alas. . . +1 for each of you.
    – HomerJ
    Commented Dec 1, 2015 at 20:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .