+ Start a Discussion
KeithlarsKeithlars 

Using custom list button to add multiple contacts to a custom object

I'm trying to add multiple contacts to my Account_Plan__c custom object by using a custom list button on the Contact object.  I have this working with the code below however, I have the account_plan_id currently hardcoded.  How would I go about displaying a lookup field to user once they click my custom list button?

{!REQUIRESCRIPT("/soap/ajax/13.0/connection.js")}

var records= {!GETRECORDIDS($ObjectType.Contact)};
var newRecords = [];

if (records[0] == null) {
    alert("Please select at least one record")
    }
else {
    for (var n=0; n<records.length; n++) {
    var c = new sforce.SObject("Account_Team_Members__c");

    c.ContactID__c = records[n];
    c.Account_Plan_ID__c = "a0YR0000000F5ls";
    newRecords.push(c);
    }

var errors = [];
var result = sforce.connection.create(newRecords);
if (result && result.length){
    var numFailed = 0;
    var numSucceeded = 0;
    for (var i = 0; i < result.length; i++){
        var res = result[i];
        if (res && res.success == 'true'){
            numSucceeded++;
        }
       else {
           var es = res.getArray("errors");
           if (es.length > 0) {
               errors.push(es[0].message);
           }
           numFailed++;
       }
    }
    if (numFailed > 0){
        alert("Failed: " + numFailed + "\nSucceeded: " + numSucceeded + " \n Due to: " + errors.join("\n"));
    }
    else {
        alert("Number of records added: " + numSucceeded);
    }
}

window.location.reload();
}

Best Answer chosen by Admin (Salesforce Developers) 
KeithlarsKeithlars
System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Account_Team_Members__c.ContactID__c

Class.contactSetExt.createMembers: line 26, column 42
External entry point


To fix the error above all I had to do was add contactid__c to the select statement in the for loop below.

        for(Account_Team_Member__c m:[select id from account_team_member__c where account_plan__c = :planId and contact__c in :contacts]) {
            existingMemberContactIds.add(m.contact__c);   
        }


All Answers

mtbclimbermtbclimber
Can you post your entire Visualforce page please?
KeithlarsKeithlars
Currently the code I listed in the initial post is part of a custom button on the Contact object.  I create the VS page
below following the developers guide for cloud computing, but this is for updating records
associated with the Account_Team_Members__c object which is where I want to insert
contacts into.   I'm trying to figure out how to display the records I select from the Contact
view on a VS page that would allow the user to select an Account_Plan__c record before the records are inserted.

Code:
<apex:page standardController="Account_Team_Members__c"
    recordSetVar="Acct_Team_Members">
    <apex:form >
    <apex:sectionHeader title="Mulitple Record Add"/>
        <apex:pageBlock mode="edit">
            <apex:pagemessages />
            <apex:pageBlockSection title="Select value to be assigned to all contacts below.">
            <apex:inputField value="{!Account_Team_Members__c.Account_Plan_ID__c}"/>
               </apex:pageBlockSection>
            <apex:pageBlockSection title="Selected Contacts">
                <apex:pageBlockTable value="{!selected}" var="c">
                    <apex:column value="{!c.ContactID__c}"></apex:column>
                    <apex:column value="{!c.Title__c}"></apex:column>
                </apex:pageBlockTable>
                <apex:actionSupport event="onchange"  status="ActionStatus"  />

                    <!--   <apex:actionStatus id="ActionStatus" startText="Please Wait" onstart="BtnDisable()" onstop="BtnEnable()" ></apex:actionStatus> -->
                    <apex:actionStatus id="ActionStatus" onstart="addRecords()"></apex:actionStatus>
            </apex:pageBlockSection>
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Add Selected Contacts" action="{!save}"/>                
                <apex:commandButton value="Cancel" action="{!cancel}"/>
                <script>
                function addRecords() {


                    var records= {!GETRECORDIDS($ObjectType.Contact)};
                    var newRecords = []; 
                    
                    if (records[0] == null) { 
                        alert("Please select at least one record") 
                        } 
                    else { 
                        for (var n=0; n<records.length; n++) { 
                            var c = new sforce.SObject("Account_Team_Members__c"); 
                    
                            c.ContactID__c = records[n];
                            c.Account_Plan_ID__c = "a0YR0000000F5ls"; 
                            newRecords.push(c); 
                            } 
                        }
               </script>

            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

mtbclimbermtbclimber
Thanks for posting the page, it's helping understand your objective.

So if I get this straight, your requirement is to have a list button for contact that allows your user to select multiple contacts from a list of contacts and on the resulting screen select one Account_Plan__c object and an action to create/update a many-to-many object, Account_Team_Member__c for each contact selected pointing to the same Account_Plan__c across them all. 

Is that right?
KeithlarsKeithlars
Almost.  I would only be adding records.  Iif they already exist, I would ignore them.  Just so you have the whole picture, Account_Team_Member__c is a related list on the Account_Plan__c object.  Each year and  Account_Plan__c record will be created for each major account and the current account team members will be added to the Account_Team_Member__c object via this new process.


KeithlarsKeithlars

Andrew,

 

Did you see my response to your question.

 

"Almost.  I would only be adding records.  Iif they already exist, I would ignore them.  Just so you have the whole picture, Account_Team_Member__c is a related list on the Account_Plan__c object.  Each year and  Account_Plan__c record will be created for each major account and the current account team members will be added to the Account_Team_Member__c object via this new process."

 

Thanks.

Keith

mtbclimbermtbclimber

You've confused me a bit.

 

I get that you need not update existing members, only add. But you lost me with the last part about cloning the prior year's team.  Is the prior year's team the source of your list of contacts, i.e. your flow starts from the member related list on a prior year's plan?

KeithlarsKeithlars
Cloning a prior year's team would be a separate process.  I need to first concentrate on getting things to work using the contact object as my source.
mtbclimbermtbclimber

Ok. you shouldn't have to use the Ajax Toolkit to accomplish this task.  What you are going after sounds sort of like the "Add to Campaign" button you'll find on the contact list page ("/003" ) .

 

I've cooked up a brief example that shows how you might mimic that with a custom "Account_Plan__c" object where the junction between that and Contact is "Account_Team_Member__c".  Hopefully you (and anyone reading this later can adjust this example to their needs).

 

After you create a page/controller extension per below then you can create a list button for Contact which can then be added to the Contacts list view page.

 

 

Here you go....

 

Page:

 

<apex:page standardController="Contact" recordSetVar="Contacts" extensions="contactSetExt">
<apex:form>
<apex:pageBlock>
<apex:pageMessages/>
<apex:pageBlockButtons>
<apex:commandButton value="Go" action="{!createMembers}"/>
</apex:pageBlockButtons>
<apex:pageBlockSection>
<apex:pageBlockSectionItem>
<apex:outputLabel value="Account Plan" for="plan"/>
<apex:outputPanel>
<apex:selectList value="{!planId}" size="1">
<apex:selectOptions value="{!planOptions}"/>
</apex:selectList>
</apex:outputPanel>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection title="Selected Contacts" columns="1">
<apex:pageBlockTable value="{!selected}" var="c">
<apex:column value="{!c.name}"/>
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

 

 Extension Class:

 

 

public class contactSetExt {

List<Contact> contacts;
public contactSetExt(ApexPages.StandardSetController controller) {
contacts = (List<Contact>) controller.getSelected();
}

public Id planId { get; set; }

public List<ApexPages.SelectOption> getPlanOptions() {
List<ApexPages.SelectOption> options = new List<ApexPages.SelectOption>();
options.add(new ApexPages.SelectOption('','--SELECT--'));

for(Account_Plan__c p:[select name from account_plan__c order by name asc]) {
options.add(new ApexPages.SelectOption(p.id, p.name));
}

return options;
}

public PageReference createMembers() {
/* see if there are existing members for this plan */
Set<Id> existingMemberContactIds = new Set<Id>{};

for(Account_Team_Member__c m:[select contact__c from account_team_member__c where account_plan__c = :planId and contact__c in :contacts]) {
existingMemberContactIds.add(m.contact__c);
}

List<Account_Team_Member__c> newMembers = new List<Account_Team_Member__c>();

for(Contact c:contacts) {
if(!existingMemberContactIds.contains(c.id)) {
newMembers.add(new Account_Team_Member__c(account_plan__c = planId, contact__c = c.id));
}
}

PageReference p;

if(newMembers.size() > 0) {

try {
Database.insert(newMembers);
p = new ApexPages.StandardController(new Account_Plan__c(id = planId)).view();
} catch (System.DMLException e) {
ApexPages.addMessages(e);
}

}

return p;
}

}

Message Edited by mtbclimber on 02-03-2009 06:46 AM
KeithlarsKeithlars

That worked for adding account team members that don't already exist. 

However, I'm trying to figure out why I get the error below when an account team member is already there.

 

System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Account_Team_Members__c.ContactID__c

Class.contactSetExt.createMembers: line 26, column 42
External entry point

 

Let me know if you see something missing.  In the meantime I work on it.

 

Thanks so much, this really helps.

 

Keith

 

KeithlarsKeithlars

I forgot to mention that my object name is account_team_members__c and my lookup field name is contactID__c.

 

 

System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Account_Team_Members__c.ContactID__c

Class.contactSetExt.createMembers: line 26, column 42
External entry point

 

KeithlarsKeithlars
System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Account_Team_Members__c.ContactID__c

Class.contactSetExt.createMembers: line 26, column 42
External entry point


To fix the error above all I had to do was add contactid__c to the select statement in the for loop below.

        for(Account_Team_Member__c m:[select id from account_team_member__c where account_plan__c = :planId and contact__c in :contacts]) {
            existingMemberContactIds.add(m.contact__c);   
        }


This was selected as the best answer
mtbclimbermtbclimber

I updated the code in my response above to address the bug you found.

 

Message Edited by mtbclimber on 02-03-2009 06:48 AM
MohaMoha
hey, i have a problem looks similar to your answer, i need to select many contacts then by cliking the INVITE button i want to create different records that belong to another custom object with a specified picklist value for every contact in the selected list
anyhelp would be great Thanks :)