I've been asked to create a custom visualforce element to replace the Campaign History related list on contact. Everything appears to be working as expected, except that the last requirement is to put the "Add to Campaign" button on the new element.

I've tried using the apex:commandButton syntax, but when clicked, it throws errors (most recently, "Formula expression is required on the action attributes") I just want the button to do the same thing it did when on the standard related list. Open a new window with the Campaign lookup, and then go to the Member record. Nothing in that process has changed. Below is the page code:

<apex:page standardController="Contact" extensions="CampaignHistoryExtension">
        <apex:pageBlock >

                <apex:commandButton action="{AddToCampaign}" value ="Add to a Campaign"/>

            <apex:outputLink target="_new" value="/701?rlid=RelatedCampaignList&id={!contact.id}">
                <p>Show All</p>

            <apex:pageBlocktable value="{!campaignMemberRecords}" var="member" rows="5" >
                <apex:column value="{!member.campaign.name}" HeaderValue="Campaign Name"/>
                <apex:column value="{!member.campaign.startdate}" HeaderValue="Campaign Start Date"/>
                <apex:column value="{!member.campaign.type}" HeaderValue="Campaign Type"/>
                <apex:column value="{!member.status}" HeaderValue="Member Status"/>
                <apex:column value="{!member.lastmodifieddate}" HeaderValue="Member Status Last Update"/>

            <apex:outputLink target="_new" value="/701?rlid=RelatedCampaignList&id={!contact.id}">


I'm assuming I'm forgetting something really obvious. Thank you for any input.

Here's the extension, per the request below:

//VF extension, designed to extend the Contact standard controller to display a filtered campaign history list
public class CampaignHistoryExtension {

//this is the Contact ID variable passed by the standard controller
    private ID thisContactID;

//List variable of campaign member records to return to the page as the sorted campaign list
    private transient List<campaignMember> campaignMemberRecords;

//Constructor to extend the standard Contact controller a\@param controller
//@param the standardController object constructed by specifying the standardControler attribute in an apex:page
    public CampaignHistoryExtension(ApexPages.StandardController controller) {
        thisContactID = controller.getId();

//@return the list of Campaign Member records to present as the campaign history
    public LIST <CampaignMember> getCampaignMemberRecords(){
        return campaignMemberRecords;

//refresh the list of campaign member records presented as teh contact campaign history by qurying the db using known properties as filter
    private void refreshCampaignMemberRecords(){
        campaignMemberRecords = [
            SELECT ID, CampaignID, Campaign.Name, Campaign.StartDate, ContactID, Contact.Name, Status, 
                Campaign.Type, campaign.Parent_Campaign__c, LastModifiedDate
            FROM CampaignMember
            WHERE ContactID = :thisContactID
            AND Campaign.Parent_Campaign__c=TRUE
            ORDER BY Campaign.StartDate DESC];

To reiterate, the VF page renders perfectly, it's just the adding of the "Add To Campaign" button that is the issue.

  • can you post your extension class
    – sfdc
    Commented Dec 4, 2014 at 17:58

1 Answer 1


the reason for the error is the action attribute has to look like {!xxx}.

If you have an action method in your controller extension called addToCampaign(), then change the commandbutton to read like:

  <apex:commandButton action="{!addToCampaign}" value ="Add to a Campaign"/>

If you aren't overriding the addToCampaign action in your controller, then use

  <apex:commandButton action="{!URLFOR($Action.Contact.AddtoCampaign,Contact.id,[retURL=$CurrentPage.URL])}" 
                      value ="Add to a Campaign"/>
  • I tried that originally but get the same error. Is there something additional that I'm forgetting about the action? Maybe it's not the commandButton syntax at all?
    – HomerJ
    Commented Dec 4, 2014 at 18:02
  • as per sf.dev; post your controller extension class; the signature for the addToCampaign method needs to be public PageReference addtoCampaign() {..}
    – cropredy
    Commented Dec 4, 2014 at 18:05
  • extension added above (can't format from iPad, sorry) Why would the extension impact the standard controller and it's actions?
    – HomerJ
    Commented Dec 4, 2014 at 18:08
  • i see you didn't have a method called addToCampaign() in your controller - I suggested a workaround in my answer
    – cropredy
    Commented Dec 4, 2014 at 18:36
  • I look forward to trying the URL-reference commandButton. Fingers crossed!
    – HomerJ
    Commented Dec 4, 2014 at 18:50

You must log in to answer this question.

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