function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Squire Q KershnerSquire Q Kershner 

Custom Campaign Related List on Contact

My team has been asked to filter the Campaign History related list to only display "Active" Campaigns.  
Since you can't filter with clicks, I assume I'll be needing to create a visualforce page that displays the filtered list,and then insert it into the page while removing the preexisting related list. The problem is that I'm not entirely sure where to start.

First question: Am I on the right track? The request is to only display Contacts with the "primary contact" checkbox selected on the account.

Second question: I've done simple visualforce related lists and some VF reports using standard controllers (thanks Mr. Workbook!) but this one is trickier because of the filter.  I assume I'm going to need an extension to query for the related campaigns via the member record.  This is where my skills start to drop off.

Third:  I am more than willing to read/tutorial/play so any suggestions for documentation, examples, or otherwise is acceptable.  Can anyone recommend a place to start there?
Squire Q KershnerSquire Q Kershner
Apologies:  Corrections to above.

Question 1:  Display only "Active Campaigns" related to the contact.  I've already figured out that I need to go from Contact, to Campaign Member, to Campaign but my query doesn't appear to be working.  Thanks in advance.
Squire Q KershnerSquire Q Kershner
More info:
So, here's my class (so far)

public class activeCampaignsExtension {

    public static void getData(id thisContact){
        list<campaignmember> cm = [select id,campaignid from campaignmember where contactid =:thisContact];

        list<campaign> camp = new list<campaign>();
        for(campaignmember tempCM: cm){
            campaign c = [select name, isactive from campaign where id=:tempCM.campaignid];
                if(c.isactive == TRUE){

If I call this from EAC, using:
I get the expected output in the debug logs.

I've pretty much reduced my Visualforce page to ruins by playing with it, so an updated version is coming.  But I use the standard Contact controller on the page, and add the extension.  I'll follow up with the VF page asap.
Marty C.Marty C.
Hello, HomerJ, I hope the sample page and Visualforce extension below will get you started with your own page.

 * Visualforce extension, designed to extend a standard Contact controller
 * with the purpose of displaying a filtered campaign history
public class CampaignHistoryExtension {

     * The Contact ID for the contact, serving as the context for
     * retrieving and presenting campaign history
    private Id contactId;

     * The list of Campaign Member records to present
     * as the campaign history
    private transient List<CampaignMember> campaignMemberRecords;
     * Constructor for extending a standard controller, assumed
     * to be a standard Contact controller
     * @param controller
     *            the StandardController object constructed by specifying
     *            the standardController attribute in an apex:page
    public CampaignHistoryExtension(ApexPages.StandardController controller) {
        contactId = 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 the contact's
     * campaign history by querying the database, using known properties
     * as query filters
    private void refreshCampaignMemberRecords() {
        campaignMemberRecords = [
            SELECT Id,
            FROM CampaignMember
            WHERE ContactId = :contactId
            AND Campaign.IsActive = TRUE
            ORDER BY Campaign.StartDate DESC

<apex:page standardController="Contact" extensions="CampaignHistoryExtension">
        <apex:pageBlockTable value="{!campaignMemberRecords}" var="member">
            <apex:column value="{!member.Campaign.Name}"/>
            <apex:column value="{!member.Campaign.StartDate}"/>
            <apex:column value="{!member.Contact.Name}"/>
            <apex:column value="{!member.Id}"/>

I think there are some core Visualforce concepts that you may want to review as you continue developing this Visualforce page on your own:
  • Why extend a standard controller? In your case, you need to extend a standard controller, because otherwise Salesforce will not let you add that Visualforce page to your page layout.
  • What is a controller or extension "property" in Visualforce?
  • What's the difference between static vs. instance methods in a controller or extension?

Each of these concepts take some time to learn and understand. I would recommend as a starting point that you go through the Visualforce Workbook[1], available for free from