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
ckellieckellie 

How do I update records from VF page

I am working on a visualforce list where I have rendered a list of records and will be changing status field and updating the actual records that have changed. Below is the wrapper class I have thus far.

public class wrapperUpdateClass {

    public wrapperUpdateClass(ApexPages.StandardController controller) {

    }

    //Our collection of the class/wrapper objects cmList
    public List<cCampaignMemberStatus> cmList {get; set;}
    
    //This method uses a simple SOQL query to return a List of CampaignMembers
    public List<cCampaignMemberStatus> getCampaignMemberStatus(){
        if(cmList == null) {
           cmList = new list<cCampaignMemberStatus>();
           for(CampaignMemberStatus cm : [select id, Label from
               CampaignMemberStatus limit 10]) {
                   cmlist.add(new cCampaignMemberStatus(cm));
               }
        }
        return cmList;
    }

    public PageReference UpdateAll() {
    List<CampaignMember> campmem = new List<CampaignMember>();
    
   // for(CampaignMember    
    
    return null;
    }
    
    // This is our wrapper/container class. A container class is a class, a data structure, or an abstract data type whose instances 
    // are collections of other objects, will contain the standard CampaignMember object
    public class cCampaignMemberStatus {
        public CampaignMemberStatus ccm {get; set;}
        
    //This is the constructor method. When we create a new cCampaignMember object we pass a CampaignMemberthat is set to the ccm property.

        public cCampaignMemberStatus (CampaignMemberStatus cm) {
            ccm = cm;
    }
    }


}

 Here is the code for the button i have thus far:

    public PageReference UpdateAll() {
    List<CampaignMember> campmem = new List<CampaignMember>();
    
 
    
    return null;
    }

 

Based on the wrapper class example (http://wiki.developerforce.com/index.php/Wrapper_Class) I need to write a for loop to capture all of the records where I have changed the campaignmemberstatus. i cannot figure that out. How doi I complete the page reference for UpdateAll?

 

Thank you,

ckellie

Kevin SwiggumKevin Swiggum

Tricky. 

So I think there's a couple of things you need to do. 

 

First, you need to set up something in your inner class that lets you determine if the record was changed on the VF page. My preference when using an inner class is to add another variable that holds the original value so that I can compare later.

 

public class cCampaignMemberStatus {

    public CampaignMemberStatus ccm {get; set;}
    public String originalLabel {get; set;}

    public cCampaignMemberStatus (CampaignMemberStatus cm) {
        ccm = cm;
        originalLabel = cm.label;
    }
}

 

You could do the same thing with the other changeable fields (HasResponded or SortOrder)

 

Next, use that comparison when building your update list

public PageReference UpdateAll() {
    if (cmList != null && cmList.size() > 0) {
        List<CampaignMember> campmem = new List<CampaignMember>();
        for (cCampaignMemberStatus ccmStat : cmList) { //loop through the list of inner class objects
            if (ccmStat.ccm.label != ccmStat.originalLabel) {
                //Adds the CampaignMemberStatus object to the list if the label has changed.
                campmem.add(ccmStat.ccm);
            }
        }
 
        update campmem; //this will update all records in the list
    }
    return null; 
}

 

That should update only those CampaignMemberStatus records that were changed by the user. Note you can use the "update" method on a list of objects just as easily as a single object. We're only going through the loop process since you're using the Inner Class cCampaignMemberStatus...the loop is pulling the actual sObject out of that inner class and putting it into a list of CampaignMemberStatus objects.

 

An important note: It looks like you're pulling from the list of CampaignMemberStatus without any filters. Campaign Member Status lists are set for each campaign....so you may need to update your page logic to get at the campaign id (perhaps by making campaign the value for the page's standardController or passing in a request parameter.

 

As an aside, as an argument for simplicity, there's really no reason to use the inner class or check if something has changed. If you tossed out the cCampaignMemberStatus inner class entirely and worked directly with the CampaignMemberStatus sObject, it would still work. You would not be limiting updates to just those records that were changed...you would be saving the entire list whether there were changes or not (but if the user didn't change anything on the VF page, then no big deal...just updates the timestamp). However, you may have other business logic reasons that make the inner class relevant...just thought I'd mention it.

 

Hope that helps

--Kevin

ckellieckellie

Kevin,

 

Thank you for the informative posting. I have been studying and trying to implement your suggestions. Since my posting, I have made  a key change to the code, making the situation a bit easier. I have been attempting to aggregate the available status values in the campaignmemberstatus object. As I have not been successful on that front, I am noting the default campaign status values using the selectOption notation. This has allowed me to deal soleley with the campaignmember sObject.

 

I liked the sidenote of not using a wrapper class and updating all records listed in the visualforce list, but I am needing to keep the updates limited to the actual records updated.

 

I have taken your recopmmended code and adapted it to the campaignmember object from the campaignmemberstatus object.  I still am not able to update the records. After looking at the debug log I found there were no records entering my test. Here is my adaptive code.

 

public class UpdateDev1Wrapper {


    public UpdateDev1Wrapper (ApexPages.StandardController controller) {

    }

    //Our collection of the class/wrapper objects cmList
    public List<cCampaignMember> cmList {get; set;}
    
    //This method uses a simple SOQL query to return a List of CampaignMemberes
    public List<cCampaignMember> getCampaignMember(){
       if(cmList == null) {
           cmList = new list<cCampaignMember>();
           for(CampaignMember cm : [select id, Status from
               CampaignMember limit 10]) {
                   cmlist.add(new cCampaignMember(cm));
               }
        }
        return cmList;
    }

    public class cCampaignMember {
    
        public CampaignMember ccm {get; set;}
        public String originalStatus {get; set;}
    
        public cCampaignMember (CampaignMember cm) {
            ccm = cm;
            originalStatus = cm.Status;
        }
    }
    
        public PageReference UpdateAll() {
            if (cmList != null && cmList.size() > 0) {
                List<CampaignMember> campmem = new List<CampaignMember>();
                for (cCampaignMember ccmStat : cmList) { //loop through the list of inner class objects
                    if (ccmStat.ccm.Status != ccmStat.originalStatus) {
                        //Adds the CampaignMember object to the list if the Status has changed.
                        campmem.add(ccmStat.ccm);
                    }
                }
         
                update campmem; //this will update all records in the list
            }
            return null; 
        }
}

 How can I change this to update changed records?

 

Thank you,

ckellie

Kevin SwiggumKevin Swiggum

Hard to tell what's going on. Can you post your visualforce code too? That might shed some light on the problem.

 

--Kevin