[SalesForce] ActionSupport: Pass record Id to Controller from apex:repeat

I'm currently returning a mass edit list. I only want to save fields that have been edited. I thought it would be efficient to have an actionsupport method that adds all edited fields to a list in order for me to save when user hits the save button. Right now I'm stuck on how to pass individual record values from a repeat list into my controller.

VisualForce:

<apex:pageblockTable value="{!campaignMemberList}" var="cm">
    <apex:column headerValue="Campaign Member Id">
         <apex:outputfield value="{!cm.id}"/> 
    </apex:column>
    <apex:column headerValue="Campaign Member picklist Field">
         <apex:inputfield value="{!cm.picklistField__c}">
             <apex:actionSupport event="onchange" action="{!cmToUpdate}"/>
         </apex:iputfield>
    </apex:column>
</apex:pageblockTable>

Part of my Apex:

private list<campaignMember> campaignMembersToUpdate = new list<campaignMember>();

//This is where I'm currently Stuck
public void cmToUpdate(){
    campaignMember cmu = new CampaignMember();
    cmu.picklistField__c = ???(Need get record value from VF page)
    cmu.id = ???(need get record value from VF page)
    campaignMembersToUpdate.add(cmu);
}

//Then this will be the method I will bind with a save button
public pageReference save(){
    if(campaignMembersToUpdate.size()>0){
        update campaignMembetstoUpdate;
    }
}

any help would be appreciated.

Best Answer

To pass the value from actionSupport to controller method, follow these steps:

  1. use apex:param with assignTo attribute to pass values to controller
  2. correctly use reRender attribute with actionSupport

Visualforce

<apex:pageblockTable value="{!campaignMemberList}" var="cm">
    <apex:column headerValue="Campaign Member Id">
         <apex:outputfield value="{!cm.id}"/> 
    </apex:column>
    <apex:column headerValue="Campaign Member picklist Field">
         <apex:inputfield value="{!cm.picklistField__c}">
             <apex:actionSupport event="onchange" action="{!cmToUpdate}" reRender="form1">
             <apex:param name="picklistFieldValue" value="{!cm.picklistField__c}" assignTo="{!picklistFieldValue}"/>
             <apex:param name="cmIdValue" value="{!cm.id}" assignTo="{!cmIdValue}"/>
             </apex:actionSupport>
         </apex:iputfield>
    </apex:column>
</apex:pageblockTable>

Controller

To capture values from assignTo declare 2 variables picklistFieldValue and cmIdValue where values of picklist and cm.id will get assigned.

private list<campaignMember> campaignMembersToUpdate = new list<campaignMember>();

public String picklistFieldValue {get;set;} //capture value from assignTo
public String cmIdValue {get;set;} //capture value from assignTo

public void cmToUpdate(){
    campaignMember cmu = new CampaignMember();
    cmu.picklistField__c = picklistFieldValue; //(Need get record value from VF page)
    cmu.id = cmIdValue; //(need get record value from VF page)
    campaignMembersToUpdate.add(cmu);
}

//Then this will be the method I will bind with a save button
public pageReference save(){
    if(campaignMembersToUpdate.size()>0){
        update campaignMembetstoUpdate;
    }
}