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
Merry SMerry S 

How do I save data to custom objects from visualforce page that uses a wrapper class extension?

In the wrapper class (which I am using and not even really sure I HAVE to), I am getting data from Accounts, contacts, and 2 custom objects. In my vf page I have 5 different sections - 1 updates account data, one updates information from both custom objects, one updates info for just one of the custom objects, one updates contacts, and one updates accounts again - but using a wrapper to get the parent accounts.

I have figured out the easiest part (updating the first account section) but cannot for the life of me figure out how to save data (from an inline edit) back to the other objects (I have not tried contacts, just trying to get the custom objects).

Here is my class extension (page uses standard account controller with this extension).
public with sharing class RoadMapAccount {

    private final Account account;
    public list<wrapperclass> accountlist1wrap { get; set; }
    public list<wrapperclass> purchasedwrap{ get; set; }
    public list<wrapperclass> implementedwrap { get; set; }
    public list<wrapperclass> plannedwrap{ get; set; }
    public list<wrapperclass> roadmapwrap { get; set; }
    public list<wrapperclass> contactwrap { get; set; }
         
        
    public RoadMapAccount(ApexPages.StandardController controller) {

        account = [Select Id, Name, Product_Interested__c, Account_Management_Type__c,
        Overall_Status__c, Opportunity_Order_Status__c, NPS_Status__c,Case_Status_Stoplight__c,
        MSA_Status__c, Risk_Status__c, Version_Status__c, Team_Management_Status__c, Escalate_Button__c,
        Wall_of_Success__c, Escalated_Reason__c, Account_Alias__c, parentid, parent_install__c, type,
        Parent.Name,Parent_Install__r.Name,(Select Id, Product_Status__c From MC_Assets__r)
         From Account where Id = :ApexPages.currentPage().getParameters().get('id')];
        
         list<Account> object0 = [
         Select parentid, parent_install__c, Account_Alias__c, Type, Name,
        Parent.Name,Parent_Install__r.Name
         from Account
         WHERE parentid =:account.Id OR parent_install__c =:account.Id];

         list<MC_Products__c> object1 = [
            Select Product_Status__c, Id, Name 
            From MC_Products__c
            WHERE Account__c =:account.Id]; 

        list<IS_RoadMap__c> object2 = [
            Select Id, Depts_using_Training__c, Depts_using_Documents__c, Account_Name__c,
            Product_Planned_to_Purchase__c, Phase_date__c, Depts_using_Risk__c,
            Depts_using_Supplier__c, Depts_using_Audit__c, Depts_using_Process__c, Next_Phase_Implementation_Notes__c,
            Account_Strategy__c, Current_System_concerns__c, Key_Individuals__c 
            From IS_RoadMap__c  
            WHERE Account_Name__c =:account.Id];

        list<Contact> object3 = [
        Select Id, AccountId, LastName, FirstName, Email, Title, Department_Contact__c, Viewed_Harbor_Tour__c
        From Contact
        WHERE AccountId =:account.Id];

        accountlist1wrap = new list<wrapperclass>();
        for(Account obj0: object0){
            accountlist1wrap.add(new wrapperclass(obj0));
        }            

        purchasedwrap = new list<wrapperclass>();
        for(MC_Products__c obj1: object1){
        	if(obj1.Product_Status__c == 'Purchased')
            purchasedwrap.add(new wrapperclass(obj1));
        }
        implementedwrap = new list<wrapperclass>();
        for(MC_Products__c obj1: object1){
        	if(obj1.Product_Status__c == 'Implemented')
            implementedwrap.add(new wrapperclass(obj1));        
        }
        plannedwrap = new list<wrapperclass>();
        for(MC_Products__c obj1: object1){
          if(obj1.Product_Status__c == 'Plan to Implement')
            plannedwrap.add(new wrapperclass(obj1));        
        }
        roadmapwrap = new list<wrapperclass>();
        for(IS_RoadMap__c obj2: object2){
            roadmapwrap.add(new wrapperclass(obj2));
        }
        contactwrap = new list<wrapperclass>();
        for(Contact obj3: object3){
            contactwrap.add(new wrapperclass(obj3));
        }

     }    

    

    public class wrapperclass{
        public Account object_0{get;set;}
        public MC_Products__c object_1{get;set;}
        public IS_RoadMap__c object_2{get;set;}
        public Contact object_3{get;set;}        

        public wrapperclass(Account obj0){
            this.object_0 = (obj0);
        }
         public wrapperclass(MC_Products__c obj1){
            this.object_1 = (obj1);
        }
        public wrapperclass(IS_RoadMap__c obj2) {
            this.object_2 = (obj2);
        }
        public wrapperclass(Contact obj3) {
            this.object_3 = (obj3);
        }  
}
    

	public Account getaccount() {
        return account;    
     } 
    public void saveRM()
    { account.RoadMap__c=True;
        try{   
        update account; 
     
        }
        catch(Exception e)
        {
        }
    }
        public boolean roadmap {
        get {
            return [
                    select Roadmap__c
                    from Account
                    where Id =:account.Id
                    ].Roadmap__c;
        }
    }
    public void saveacc()
    {
        try{   
        update account;
        
     
        }
        catch(Exception e)
        {
        }
    }            
 
}

Visual force page (this will eventually be a "tab" on a custom account page.) (all save buttons, other than the first one, are just there as place holders - I know they are not configured correctly)
<apex:page Standardcontroller="Account" extensions="RoadMapAccount"
            sidebar="false" showheader="false">
            <base target="_parent" />

<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"/>
<script>
    j$ = jQuery.noConflict();
    
    function showLoadingDiv() {
        var newHeight = j$("[id$=lead-edit-section] .pbSubsection").css("height");//Just shade the body, not the header
        j$("[id$=loading-curtain-div]").css("background-color", "black").css("opacity", 0.35).css("height", newHeight).css("width", "80%");
    }
    function hideLoadingDiv() {
        j$("[id$=loading-curtain-div]").css("background-color", "black").css("opacity", "1").css("height", "0px").css("width", "80%");
    }
    
   function pageScroll() {
        window.scrollBy(0,400); // horizontal and vertical scroll increments
        
    }
 </script> 
 <style>
 input.btn { 
     color:#050; 
     font: bold 84% 'trebuchet ms',helvetica,sans-serif; 
     background-color:#fed; 
     border:1px solid; 
     border-color: #696 #363 #363 #696; 
   }
 </style>   
    <apex:form >
 <apex:pageblock title="RoadMap">
                    <apex:pageBlock rendered="{!Not (roadmap)}">
                <apex:pageBlockButtons location="top" >
                     <apex:commandbutton onclick="pageScroll()" value="Create RoadMap" action="{!saveRM}"  id="rmbutton" />
                </apex:pageBlockButtons><br />
                <apex:pageMessage summary="Click 'Create RoadMap' to get started" severity="info" strength="3" />
                   </apex:pageBlock>   

    <apex:pageMessages />
     <apex:actionRegion >
      <apex:pageBlock id="account-edit-block">
        <apex:actionStatus id="save-account-status"/>
          <apex:pageBlockSection title="Account Information" columns="2" collapsible="false" id="account-edit-section">
            <div></div>
            <apex:pageblockSectionItem ></apex:pageblockSectionItem>
            <apex:outputField value="{!account.name}">
            <apex:inlineEditSupport event="onclick"/>
            </apex:outputfield> 
            <apex:outputField value="{!account.Account_Alias__c}">
            <apex:inlineEditSupport event="onclick"/>
            </apex:outputfield> 
            <apex:outputField value="{!account.type}">
            <apex:inlineEditSupport event="onclick"/>
            </apex:outputfield> 
          </apex:pageBlockSection>
            <center><apex:commandButton action="{!saveacc}" value="Save Account Information" status="save-account-status" rerender="account-edit-block"/></center>
     </apex:pageBlock>
    </apex:actionRegion>  

<apex:outputpanel id="fullmap">
     <apex:outputpanel rendered="{!roadmap}">

    <apex:pageMessages />
     <apex:actionRegion >
      <apex:pageBlock id="product-edit-block">
        <apex:actionStatus id="save-product-status"/>
          <apex:pageBlockSection title="Product Details" id="product-edit-section">
            <div></div>
            <apex:pageblockSectionItem ></apex:pageblockSectionItem>
            <apex:panelGrid columns="2" width="1350px">
        <apex:pageblock >
         <apex:pageblocktable value="{!purchasedwrap}" var="pur" id="Pdetails">
          <apex:column headerValue="Purchased">
          <apex:repeat var="a" value="{!pur.object_1}">
          <apex:outputText value="{!a.name}"/>
           </apex:repeat>
          </apex:column>         
          <apex:column headerValue="Status">
          <apex:repeat var="a" value="{!pur.object_1}">
          <apex:outputField value="{!a.Product_Status__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column>   
        </apex:pageblocktable>
       </apex:pageblock>

        <apex:pageblock >
         <apex:pageblocktable value="{!implementedwrap}" var="imp" id="Idetails">
          <apex:column headerValue="Implemented">
          <apex:repeat var="a" value="{!imp.object_1}">
          <apex:outputText value="{!a.name}"/>
           </apex:repeat>
          </apex:column>         
          <apex:column headerValue="Status">
          <apex:repeat var="a" value="{!imp.object_1}">
          <apex:outputField value="{!a.Product_Status__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column>   
          </apex:pageblocktable>
         </apex:pageblock>

        <apex:pageblock mode="inlineEdit" >
         <apex:pageblocktable value="{!plannedwrap}" var="pln" id="PIdetails">
          <apex:column headerValue="Planned to Implement">
          <apex:repeat var="a" value="{!pln.object_1}">
          <apex:outputText value="{!a.name}"/>
           </apex:repeat>
          </apex:column>         
          <apex:column headerValue="Status">
          <apex:repeat var="a" value="{!pln.object_1}">
          <apex:outputField value="{!a.Product_Status__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column>
         </apex:pageblocktable>
        </apex:pageblock>

        <apex:pageblock >
         <apex:pageblocktable value="{!roadmapwrap}" var="rm" id="PPdetails">
          <apex:column headerValue="Products Planned Purchased">
          <apex:outputfield value="{!rm.object_2.Product_Planned_to_Purchase__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          <apex:column headerValue="Phase Date">
          <apex:outputfield value="{!rm.object_2.Phase_date__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>          
          </apex:column>
          <apex:column >
          <apex:commandbutton value="Remind Me" action="/00T/e?what_id={!account.Id}&tsk12=Not Started&retURL=%2Fa{!account.Id}"/>
          </apex:column>
          </apex:pageblocktable>
         </apex:pageblock>
        </apex:panelGrid>
       </apex:pageBlockSection>
         <center><apex:commandButton action="{!save}" value="Save Product Information" status="save-product-status" rerender="product-edit-block"/></center>
     </apex:pageBlock>
    </apex:actionRegion> 



    <apex:pageMessages />
     <apex:actionRegion >
      <apex:pageBlock id="dept-edit-block">
        <apex:actionStatus id="save-dept-status"/>
          <apex:pageBlockSection title="Department Information" id="dept-edit-section">
            <div></div>
            <apex:pageblockSectionItem ></apex:pageblockSectionItem>
                <apex:panelGrid columns="6" width="1350px">

        <apex:pageblock mode="inlineEdit" >
         <apex:pageblocktable value="{!roadmapwrap}" var="rmd" id="depts1">
           <apex:column headerValue="Depts using Documents">
          <apex:outputfield value="{!rmd.object_2.Depts_using_Documents__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>

         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="rmp" id="depts2">
           <apex:column headerValue="Depts using Process">
          <apex:outputfield value="{!rmp.object_2.Depts_using_Process__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>

         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="rmt" id="depts3">
           <apex:column headerValue="Depts using Training">
          <apex:outputfield value="{!rmt.object_2.Depts_using_Training__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>

         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="rma" id="depts4">
           <apex:column headerValue="Depts using Audit">
          <apex:outputfield value="{!rma.object_2.Depts_using_Audit__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>

         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="rms" id="depts5">
           <apex:column headerValue="Depts using Supplier">
          <apex:outputfield value="{!rms.object_2.Depts_using_Supplier__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>

         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="rmr" id="depts6">
           <apex:column headerValue="Depts using Risk">
          <apex:outputfield value="{!rmr.object_2.Depts_using_Risk__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>
         </apex:panelGrid> <br />
                <apex:panelGrid columns="1" width="1350px">
         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="n" id="notes">
           <apex:column headerValue="Next Phase Implementation Notes">
          <apex:outputfield value="{!n.object_2.Next_Phase_Implementation_Notes__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         </apex:pageblock>
                                                      
         </apex:panelGrid>
      </apex:pageBlockSection>
         <center><apex:commandButton action="{!save}" value="Save Dept Information" status="save-dept-status" rerender="dept-edit-block"/></center>
     </apex:pageBlock>
    </apex:actionRegion> 

    <apex:pageMessages />
     <apex:actionRegion >
      <apex:pageBlock id="strat-edit-block">
        <apex:actionStatus id="save-strat-status"/>
          <apex:pageBlockSection title="Account Notes and Account Strategy" id="strat-edit-section">
            <div></div>
            <apex:pageblockSectionItem ></apex:pageblockSectionItem>
            <apex:panelGrid columns="1" width="1350px">
        <apex:pageblock title="Associated Contacts" mode="inlineEdit">
         <apex:pageblocktable value="{!contactwrap}" var="con" id="contact">
          <apex:column headerValue="Name">
          <apex:repeat var="c" value="{!con.object_3}">
          <apex:outputlink value="{c.id}"><apex:outputField value="{!c.FirstName}"/><apex:outputField value="{!c.LastName}"/></apex:outputlink>
          </apex:repeat>
          </apex:column>  
          <apex:column headerValue="Title">
          <apex:repeat var="c" value="{!con.object_3}">
          <apex:outputField value="{!c.title}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column>   
          <apex:column headerValue="Department">
          <apex:repeat var="c" value="{!con.object_3}">
          <apex:outputField value="{!c.Department_Contact__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column>   
          <apex:column headerValue="Email">
          <apex:repeat var="c" value="{!con.object_3}">
          <apex:outputField value="{!c.email}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>              
          </apex:repeat>
          </apex:column> 
         <apex:column headerValue="Viewed Harbor Tour" value="{!con.object_3.Viewed_Harbor_Tour__c}" />
          </apex:pageblocktable>
         </apex:pageblock>
         <apex:pageblock mode="inlineEdit">
         <apex:pageblocktable value="{!roadmapwrap}" var="k" id="key">
           <apex:column headerValue="Key Individuals (Team details/concerns, Political layout, Newsletter Opt out…)">
          <apex:outputfield value="{!k.object_2.Key_Individuals__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         <apex:pageblocktable value="{!roadmapwrap}" var="c" id="current">
           <apex:column headerValue="Current System concerns or issues (General)">
          <apex:outputfield value="{!c.object_2.Current_System_concerns__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
         <apex:pageblocktable value="{!roadmapwrap}" var="s" id="strat">
           <apex:column headerValue="Account Strategy (Ex: Expand usage of Docs by expanding department, then focus on Training. Ex: Key Executive sponsor(s) and Champion who can expand through company)">
          <apex:outputfield value="{!s.object_2.Account_Strategy__c}">
          <apex:inlineEditSupport event="onclick"/>
          </apex:outputfield>
          </apex:column>         
          </apex:pageblocktable>
          </apex:pageblock>
         </apex:panelGrid>
       </apex:pageBlockSection>
         <center><apex:commandButton action="{!save}" value="Save Strategy Information" status="save-strat-status" rerender="strat-edit-block"/></center>
     </apex:pageBlock>
    </apex:actionRegion> 
 
    <apex:pageMessages />
     <apex:actionRegion >
      <apex:pageBlock id="parent-edit-block">
        <apex:actionStatus id="save-parent-status"/>
          <apex:pageBlockSection title="Associated Accounts - Children and Non-Install" id="parent-edit-section">
            <div></div>
            <apex:pageblockSectionItem ></apex:pageblockSectionItem> 
                <apex:panelGrid columns="1" width="1350px">
        <apex:pageblock mode="inlineEdit" rendered="{!AND(NOT(ISNULL(accountlist1wrap)),accountlist1wrap.size>0)}">
         <apex:pageblocktable value="{!accountlist1wrap}" var="par" id="parent">
          <apex:column headerValue="Account Name">
          <apex:repeat var="p" value="{!par.object_0}">
          <apex:outputText value="{!p.Name}"/>
           </apex:repeat>
          </apex:column>
          <apex:column headerValue="Account Alias">
          <apex:repeat var="p" value="{!par.object_0}">
          <apex:outputText value="{!p.Account_Alias__c}"/>
           </apex:repeat>
          </apex:column>
          <apex:column headerValue="Account Type">
          <apex:repeat var="p" value="{!par.object_0}">
          <apex:outputText value="{!p.type}"/>
           </apex:repeat>
          </apex:column>          
          <apex:column headerValue="Parent">
          <apex:repeat var="p" value="{!par.object_0}">
          <apex:outputText value="{!p.parent.name}"/>
           </apex:repeat>
          </apex:column>  
          <apex:column headerValue="Parent Install">
          <apex:repeat var="p" value="{!par.object_0}">
          <apex:outputText value="{!p.Parent_Install__r.name}"/>
           </apex:repeat>
          </apex:column>      
          </apex:pageblocktable>
         </apex:pageblock>
        <apex:pageBlock rendered="{!OR(ISNULL(accountlist1wrap),accountlist1wrap.size=0)}">
          <apex:pageMessage summary="This account is not the Parent or Parent Install on any other accounts." severity="info" strength="3" />
         </apex:pageBlock>
         </apex:panelGrid>
        </apex:pageBlockSection>
         <center><apex:commandButton action="{!save}" value="Save Parent Information" status="save-parent-status" rerender="parent-edit-block"/></center>
     </apex:pageBlock>
    </apex:actionRegion> 
   </apex:outputpanel>             
</apex:outputpanel>   
 </apex:pageblock>        
    </apex:form>
</apex:page>

 
Best Answer chosen by Merry S
Suneel#8Suneel#8
I don't think you need a wrapper class here.As per your constructors,you are not combining the data from custom object,accounts and contacts.Each constructor is taking only one object info and you are not modifying the objects after creation.You can remove wrapper classes and refactor the code.Also try building the functionality incrementally rather than all at once.That way it is easy to understand ,debug and can easily find where code is broken

All Answers

Suneel#8Suneel#8
I don't think you need a wrapper class here.As per your constructors,you are not combining the data from custom object,accounts and contacts.Each constructor is taking only one object info and you are not modifying the objects after creation.You can remove wrapper classes and refactor the code.Also try building the functionality incrementally rather than all at once.That way it is easy to understand ,debug and can easily find where code is broken
This was selected as the best answer
Merry SMerry S
You were right - no wrapper needed. Reworking the code as you suggested worked perfectly.