0

I have (5) Visual Force components on a main Visual Force page. How can I best save all component data and main page using a save button on the main page? Would appreciate guidance with code examples that others may have done. Many thanks.

    //The main page object:        
           public Claims_Client_Risk_Assessment__c CCRA { get; set; }
    //The components page object:        
           public CCRA_LOB_NonStdAuto__c LOB_NonStdAuto { get; set; }  

           this.CCRA = (Claims_Client_Risk_Assessment__c) controller.getRecord();
           this.LOB_NonStdAuto = new CCRA_LOB_NonStdAuto__c(Name = CCRA.Name, 
             Claims_Client_Risk_Assessment__r = this.CCRA); 
           record=this.CCRA;            

            Public Void SaveTestInsert() {
                try {
                    upsert CCRA;
                    stdController.save();
                    SFDCAttachLOB();
                } catch (Exception ex) {
                    ApexPages.addMessages(ex);
                }
            }

            Public void AttachLOB() {
            try {
                   LOB_NonStdAuto.Claims_Client_Risk_Assessment__c = CCRA.id;
                   LOB_NonStdAuto.Name = CCRA.Name;
                   Upsert LOB_NonStdAuto;    
                } catch (Exception ex) {
                    ApexPages.addMessages(ex);
                }    
            }

            public PageReference saveOverride(){
             try{
              Database.update( record );
             }
             catch( Exception ex ){
              ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR, ex.getMessage() ));
              return null;
             }
             saveChildren();

             PageReference pageRef = null;
             pageRef = new PageReference('/' + this.CCRA.Id);
             pageRef.getParameters().put('inline', '0');
             pageRef.setRedirect(true);
             return pageRef;
             }

             public void saveChildren(){
              try{
               Database.update( record.CCRA_LOB_NonStdAuto__r );
              }
              catch( Exception ex ){
              system.debug( 'Error saving child: ' + ex.getMessage() );
             }
           }

The Visualforce component attributes:

<apex:component >
    <!-- Attribute Definitions -->
    <apex:attribute name="NonStdAuto" type="CCRA_LOB_NonStdAuto__c" description="CCRA non standard auto LOB" required="true"/>
    <apex:attribute name="record" type="Claims_Client_Risk_Assessment__c" description="CCRA Parent Object" required="true"/> 

Parent Visualforce Page call to component.

<c:PROD_CCRA_LOB_NonStdAuto NonStdAuto="{!LOB_NonStdAuto}" record={!Claims_Client_Risk_Assessment__c}" />

closed as too broad by glls, David Reed, battery.cord, Raul, Brian Mansfield Jul 9 '18 at 14:33

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Have you tried anything so far? I think it will be much more helpful for others here to help you, if you share your efforts and where you are stuck. – Jayant Das Jul 6 '18 at 16:26
  • Looking for ideas that others have had success with. Would appreciate some direction . Many thanks. – rickmac Jul 6 '18 at 17:21
  • @JayantDas attached code methods to do this. Obviously the upcerts are not saving the data on the components object. So I need a way to 'save' the component object from the main page's object controller. Would appreciate any insight. Thanks. – rickmac Jul 6 '18 at 19:38
2

The simple answer would be to pass the standard controller into each component. When you fire the save event for the main page standard controller, you can override the save event to handle the save and also cover the child objects ( if any ) by calling update on the ObjectName__r for these components if they exist. Your components can either have the same controller as the main page or no controller at all and only contain fields.

Sample save method would look like :

public ParentObject__c record { get; set; }

public MyController( ApexPages.standardController controller ){
    record = ( ParentObject__c )controller.getRecord();
}

public PageReference saveOverride(){
    try{
        Database.update( record );
    }
    catch( Exception ex ){
        ApexPages.addMessage( new ApexPages.Message( ApexPages.Severity.ERROR, ex.getMessage() ));
        return null;
    }

    saveChildren();

    PageReference pg = Page.currentPageName;
    pg.getParameters().put( 'id', record.Id );
    pg.setRedirect( true );

    return pg;
}

public void saveChildren(){
    try{
        Database.update( record.ChildObject__r );
    }
    catch( Exception ex ){
        system.debug( 'Error saving child: ' + ex.getMessage() );
    }
}

On your page you can contain all of your components. All components would contain an attribute to receive the standard controller object like so:

<apex:page standardController="ParentObject__c" extensions="MyController">
    <c:MycomponentOne record="{!ParentObject__c}" />
    <c:MyComponentTwo record="{!ParentObject__c}" />
    <c:MyComponentThree record={!ParentObject__c}" />
    <apex:commandButton value="Save" action="{!saveOverride}" />
</apex:page>

This should handle saving multiple components to a single save button across an object and it's children from a single save method. On your component if you have any child object fields.. You can save then through a lookup relationship or if you are saving from a child level you can save through the MasterDetail relationship name using the __r.

To update a parent level record from the child level:

ApexPages.standardController ms_controller { get; set; }
ParentObject__c thisObject { get; set; }

public MyController( ApexPages.standardController controller ){
    ms_controller = controller;

}

public void updateParentRecord() {
    try {
        thisObject = ( ParentObject__c )ms_controller.getRecord();

        if(thisObject.ChildObject__r != null) {
            update thisObject.ChildObject__r;
        }
    } 
    catch (Exception e) {
          ApexPages.addMessages(e);

    }
}

Saving child records using their token you would:

ApexPages.standardController ms_controller { get; set; }
ParentObject__c thisObject { get; set; }

public MyController( ApexPages.standardController controller ){
    ms_controller = controller;


}

public void saveChildrenObjects(){

    thisObject = ( ParentObject__c ) ms_controller.getRecord();

    if( thisObject != null ){
        SObject childRecord1 = thisObject.getSObject( thisObject.ChildObject__r );

        SObject childRecord2 = thisObject.getSObject( thisObject.ChildObject2__r );

        try{

           Database.update( childRecord1 );
           Database.update( childRecord2 );
        }
        catch( Exception ex ) { 
             ApexPages.addMessage( ex.getMessage );
        }
    }

}
  • Thanks for your informative reply. I’ll try your approach and let you know! – rickmac Jul 8 '18 at 4:15
  • getting Variable does not exist: CCRA_LOB_NonStdAuto__r at line 323 column 33. I updated the code above incorporating your suggestion. There is only a MSTR detail field from the child to the parent object so not sure if that is causing the CCRA_LOB_NonStdAuto__r reference to fail. Or perhaps I am relating it improperly ? Appreciate your eyes on this. – rickmac Jul 9 '18 at 1:55
  • Thanks @Ronnie The error is on Database.update( record.CCRA_LOB_NonStdAuto__r ); – rickmac Jul 9 '18 at 2:10
  • is your page based on the child record or on the parent record? the save using __r would work absolutely if you were on the child record. if on the parent level - you would need to use getReferenceTo() and return the object prior to saving otherwise. @rickmac – Ronnie Jul 9 '18 at 2:40
  • 1
    OK. Confused. Why is this topic placed on hold by others ? This is not a broad question so I am a little concerned about the action taken. I am appreciative of the information @Ronnie has supplied and find it interesting that others are quick to judge here. – rickmac Jul 9 '18 at 15:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.