You need to sign in to do that
Don't have an account?
RatherGeeky
Adding btn to update campaign member status to Campaign Membership Manager app
I'm trying to modify the code in the awesome Campaign Membership Manager app in order to add a button that updates the status of all selected members to a specific option (which I want to hard code).
The existing button allows the user to remove the selected members.
I, uh, added the button. But as far as developing the functionality, I'm a dum dum.
This is my button:
<apex:commandButton value="Update to Hand Deliver" action="{!updateSelectedStatusMail}" rendered="{!NOT(ISNULL(CampaignMembers))}" />
And here's the code:
/** * CMM Campaign Membership Manager * Copyright (c) 2009, Marcel Will, Sales Engineering, Salesforce.com Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ public with sharing class cmmCampaignMembershipManagerController{ private List<myCampaignMember> campaignMemberList { get; set; } private List<myCampaignMember> CampaignMembers; private List<myCampaignMember> pageCampaignMemberList; private List<CampaignMember> deleteCampaignMembers; private Map<Id, CampaignMember> selectedCampaignMembersMap; private String selectedCampaign; private String CampaignDescription; private String userName; private String userLanguage; private Integer pageNumber; private Integer pageSize; private integer totalPageNumber; private Integer selectedRows; public Boolean selectAllCheckbox { get; set; } public String messageTitle { get; set; } public String messageDetail { get; set; } public String messageSeverity { get; set; } transient public Boolean messageShow { get; set; } /** * constructor */ public cmmCampaignMembershipManagerController(){ this.CampaignMembers = new List<myCampaignMember>{}; this.pageCampaignMemberList = new List<myCampaignMember>{}; this.deleteCampaignMembers = new List<CampaignMember>(); this.selectedCampaignMembersMap = new Map<Id, CampaignMember>(); this.userName = UserInfo.getUserId(); this.userLanguage = UserInfo.getLanguage(); this.pageNumber = 0; this.totalPageNumber = 0; this.selectedRows = 0; this.pageSize = 10; } /** * Getter method to retrieve the user language * @return userLanguage */ public String getUserLanguage(){ return userLanguage.Substring( 0, 2 ); } /** * Getter Method to retrieve the current page number * @return pageNumber */ public Integer getPageNumber(){ return pageNumber; } /** * Getter method to retrieve the page size * @return pageSize */ public Integer getPageSize(){ return pageSize; } /** * Getter method to enable previous button * @return Boolean */ public Boolean getPreviousButtonEnabled(){ return !( pageNumber > 1 ); } /** * Getter method to enable Next button * @return Boolean */ public Boolean getNextButtonEnabled(){ if( campaignMemberList == null ){ return true; }else{ return ( ( pageNumber * pageSize ) >= campaignMemberList.size() ); } } /** * Getter method to retrieve total page number * @return totalPageNumber */ public Integer getTotalPageNumber(){ totalPageNumber = campaignMemberList.size() / pageSize; Integer mod = campaignMemberList.size() - ( totalPageNumber * pageSize ); if( mod > 0 ){ totalPageNumber++; } return totalPageNumber; } /** * Getter method to retrieve Campaign member list * @return List<myCampaignMember> */ public List<myCampaignMember> getCampaignMembers(){ if( pageCampaignMemberList.Size() > 0 ){ return pageCampaignMemberList; }else{ return null; } } /** * Getter to retrieve the number of selected rows * @return selectedRows */ public Integer getSelectedRows(){ return this.selectedRows; } /** * Recalculate Number of selected items in Grid * @return null */ public Integer recalculateSelected(){ selectedRows = selectedCampaignMembersMap.size(); return null; } /** * Bind data to paged list for displaying on VF page * @param newPageIndex */ private void BindData( Integer newPageIndex ){ try{ Transient Integer counter = 0; Transient Integer min = 0; Transient Integer max = 0; if( newPageIndex > PageNumber ){ min = pageNumber * pageSize; max = newPageIndex * pageSize; }else{ max = newPageIndex * pageSize; min = max - pageSize; } CampaignMembers.clear(); pageCampaignMemberList.clear(); for( myCampaignMember cm: CampaignMemberList ){ counter++; if( counter > min && counter <= max ){ pageCampaignMemberList.add( cm ); } } pageNumber = newPageIndex; if( pageCampaignMemberList == null || pageCampaignMemberList.size() <= 0 ){ messageTitle = 'CMM_No_data'; messageDetail = 'CMM_No_data_available'; messageSeverity = 'info'; messageShow = true; } }catch( Exception ex ){ messageTitle = ex.getMessage(); messageDetail = ex.getMessage(); messageSeverity = 'fatal'; messageShow = true; } } /** * Search for all Campaign Members of a selected campaign and put them into a list of <myCamapaignMember> * @return PageReference */ public PageReference DoSearch(){ this.campaignMemberList = new List<myCampaignMember>(); this.pageCampaignMemberList.clear(); for( CampaignMember cm: [ Select Id, LeadId, Lead.Company, Lead.Email, Lead.FirstName, Lead.LastName, Lead.OwnerId, Lead.City, ContactId, Contact.Account.Name, Contact.Email, Contact.FirstName, Contact.LastName, Contact.OwnerId, Contact.MailingCity, Status from CampaignMember WHERE CampaignId =: selectedCampaign AND ( Contact.OwnerID =: userName OR Lead.OwnerID =: userName ) ORDER BY Lead.LastName, Contact.LastName ] ){ this.campaignMemberList.add( new MyCampaignMember( cm ) ); } this.BindData( 1 ); this.selectedRows = 0; return null; } /** * Action method on next button * @return PageReference */ public PageReference nextBtnClick(){ clearMessage(); updateSelectedList(); BindData( pageNumber + 1 ); return null; } /** * Action method on previous button * @return PageReference */ public PageReference previousBtnClick(){ clearMessage(); updateSelectedList(); BindData( pageNumber -1 ); return null; } /** * This method clears the message on the visual force page. * @return PageReference */ public pageReference clearMessage(){ this.messageShow = false; return null; } /** * Get Campaign Description for selected Campaign to show on VF page * @return CampaignDescription */ public String getCampaignDescription(){ CampaignDescription = 'CMM_Select_Campaign'; if( selectedCampaign != null ){ Campaign myCampaign = [ select id, description from Campaign where id =: selectedCampaign ]; CampaignDescription = myCampaign.Description; } return CampaignDescription; } /** * Update list of selected records for processing */ public void updateSelectedList(){ List<myCampaignMember> members = this.getCampaignMembers(); if( members != null ){ for( myCampaignMember mcMember : getCampaignMembers() ){ if( mcMember.selected == true ){ selectedCampaignMembersMap.put( mcMember.campmem.id, mcMember.campmem ); }else{ selectedCampaignMembersMap.remove( mcMember.campmem.id ); } } selectedRows = selectedCampaignMembersMap.size(); } } /** * Delete selected campaign members * @return PageReference */ public PageReference updateSelectedStatusMail(){ updateSelectedList(); deleteCampaignMembers.clear(); deleteCampaignMembers = selectedCampaignMembersMap.values(); try{ if( deleteCampaignMembers.size() > 0 ){ delete deleteCampaignMembers; messageTitle = 'CMM_Successful'; messageDetail = deleteCampaignMembers.size() + ' ' + 'CMM_Successfully_removed'; messageSeverity = 'confirm'; messageShow = true; } else{ messageTitle = 'CMM_Error'; messageDetail = 'Please select at least one member'; messageSeverity = 'fatal'; messageShow = true; } }catch( DmlException e ){ messageTitle = 'CMM_Error'; messageDetail = e.getMessage(); messageSeverity = 'fatal'; }finally{ messageShow = true; } campaignMemberList.clear(); selectedCampaignMembersMap.clear(); selectedRows = 0; DoSearch(); return null; } /** * Update Status of Campaign Members to 'Hand Deliver' * Customization added October 18, 2011 * @return PageReference */ public PageReference processSelected(){ updateSelectedList(); campaignMemberList.clear(); selectedCampaignMembersMap.clear(); selectedRows = 0; DoSearch(); return null; } /** * Get list of all Campaigns with Status equals to "Planned" and with Active equals to "true" * @return List<SelectOption> */ public List<SelectOption> getCampaigns(){ List<SelectOption> options = new List<SelectOption>(); List<Campaign> cList = new List<Campaign>(); try { cList = [ SELECT Id, Name, Description FROM Campaign WHERE Status = 'Planned' AND IsActive = true ORDER BY Name ]; for( Campaign c: cList ){ options.add( new SelectOption( c.Id, c.Name ) ); } if( cList == null || cList.size() <= 0 ){ // Show Info Message that no records have been found messageTitle = 'CMM_No_data'; messageDetail = 'CMM_No_Campaign'; messageSeverity = 'info'; messageShow = true; return null; }else{ return options; } }catch( Exception ex ){ // Show error Message with severity FATAL // messageTitle = 'CMM_Error'; // messageDetail = ex.getMessage(); //messageSeverity = 'fatal'; //messageShow = true; return null; } } /** * Getter method to retreieve the selected campaing * @return selectedCampaign */ public String getSelectedCampaign(){ return this.selectedCampaign; } /** * Setter method to set te selected Campaign * @param selectedCampaign */ public void setSelectedCampaign( String selectedCampaign ){ this.selectedCampaign = selectedCampaign; } /** * Inner Class * myCampaignMember to extend CampaignMember object with selected field (checkbox, boolean) */ public class myCampaignMember{ public CampaignMember campmem { get; set; } public Boolean selected { get; set; } /** * Constructor */ public myCampaignMember( CampaignMember cm ){ this.campmem = cm; this.selected = false; } } }
Resolved with Kyle over the phone. The problem was that the picklist option I was trying to use was not an option for that campaign. While we expected that the code would update the picklist with any value I selected, that was apparently not the case. It has to be an existing value.
All Answers
Hi Jenna,
From what I can see, it looks like you are tryng to repurpose the class for the remove button. Your button uses the action="{!updateSelectedStatusMail}". This means you are calling the class updateSelectedStatusMail.
In that class you are calling a delete "delete deleteCampaignMembers" when you really want to be calling an update. Before you do that you need to set the status for each selected campaign member. I have updated the first few lines of the try section for the basic idea I think you are looking for. Give this a shot and let me know if that works.
Whoops. I typed over the wrong part. The delete part should still do that. I renamed the wrong section of code. I copied that and was going to rename it and remove all the references to deletions (which appears just below that).
So, basically I am trying to make a section of code that processes that selected records and rather than deleting, updates them.
Here's more what the code currently looks like.
The problem is that I don't know how to code an update like this. I can repurpose code by renaming stuff but for a different functionality, I'm stuck.
Did you try the coded that I added before. It uses the deleteCampaignMembers list, but only updates the values of status and then updates the records (it doesn't delete anything, I just reused the list that was in there to reduce the amount of changes that need to be made).
Updated this code - thanks Kyle. But, uh, it doesn't actually update the field. I have refreshed and tried verifying but still no update.
Suggestions?
Resolved with Kyle over the phone. The problem was that the picklist option I was trying to use was not an option for that campaign. While we expected that the code would update the picklist with any value I selected, that was apparently not the case. It has to be an existing value.
This was awesome and just what we were looking for! The only difference is that instead of hard-coding the value to update the member status, we want to just provide all of the possible values (like in a listbox), letting the user choose and then mass update the members to the selected status. How could we do that?
Not sure what kind of skill you have in pages and code, but the basic idea is to query for the campaign statuses based on the selectedCampaign
list<CampaignMemberStatus> statuses = [Select Label, CampaignId From CampaignMemberStatus where CampaignId=:selectedCampaign];
you then need to use that list to build a picklist of selectOptions
List<SelectOption> options = new List<SelectOption>();
for(CampaignMemberStatus c : statuses){
options.add( new SelectOption(c.Label, c.Label);
}
from there you should be able to determine the selected status and selected records when an update button is clicked and update the records accordingly.