[SalesForce] Create Multiple Child Records from Parent Record

I have two custom objects: Parent (Parent__c) and Child (Child__c). The goal here is for the user to click a button on the Child Related List and enter data in input fields to create new Child records.

Here's my code:

Controller:

public class AddingChildController {
Id parentId;
public List<Child__c> childList {get;set;}
public Integer rowNum{get;set;}

public AddingChildController(){
    Id childId = ApexPages.currentPage().getParameters().get('childId');
    childList = new List<Child__c>();
    childList.add(new Child__c());
}


public void insertChild(){
    insert childList;
}

public void insertRow(){
    childList.add(new Child__c());
}

public void delRow(){
    rowNum = 
Integer.valueof(apexpages.currentpage().getparameters().get('index'));
    childList.remove(rowNum);
}
}

Visualforce Page:

<apex:page controller="AddingChildController" >
<apex:form >
    <apex:variable var="rowNum" value="{!0}" />
    <apex:pageBlock >
        <apex:variable var="rowNum" value="{!0}" />
        <apex:PageBlockTable value="{!childList}" var="int">
        <apex:facet name="footer">
            <apex:commandLink value="Add" action="{!insertRow}"/>
            </apex:facet>
            <apex:column headerValue="Name">
                <apex:inputField value="{!int.Name}"/>                                      
            </apex:column>
            <apex:column headerValue="Age">
            <apex:inputField value="{!int.Age__c}"/>
            </apex:column>
             <apex:column headerValue="Delete">
            <apex:commandLink style="font-size:15px; font-weight:bold; text-align:center;color:red;" value="X" action="{!delRow}">
                <apex:param value="{!rowNum}" name="index"/>
                </apex:commandLink>
                <apex:variable var="rowNum" value="{!rowNum+1}"/>
            </apex:column>
        </apex:PageBlockTable>
    <apex:pageBlockButtons >
        <apex:commandButton value="Save" action="{!insertChild}"/>
        </apex:pageBlockButtons>
    </apex:pageBlock>

  </apex:form>
</apex:page>

I've created the button and I can see the Visualforce page, but when I got to save the records, I get the following error:

Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Parent]: [Parent]
Error is in expression '{!insertChild}' in component in page addchildrenvfpage: Class.AddingChildController.insertChild: line 14, column 1

Any suggestions on how to fix this?

*NEW VERSION**

 public class AddingChildController {
 Id parentId;
 public List<Child__c> childList {get;set;}
 public Integer rowNum{get;set;}

public AddingChildController(){
Id parentId = ApexPages.currentPage().getParameters().get('parentId');
childList = new List<Child__c>();
childList.add(new Child__c(Parent__c = parentId));
   }

public void insertChild(){
    insert childList;
   }

public void insertRow(){
   childList.add(new Child__c(Parent__c = parentId));
    }

public void delRow(){
rowNum = 
Integer.valueof(apexpages.currentpage().getparameters().get('index'));
    childList.remove(rowNum);
    }
   }

Best Answer

It looks like your objects are in a master-detail relationship, so the child cannot be created without a parent. In your constructor, as you create your child objects, you're not populating that parent lookup:

public AddingChildController(){
    Id childId = ApexPages.currentPage().getParameters().get('childId');
    childList = new List<Child__c>();
    childList.add(new Child__c());
}

There should be a line in here like

    childList.add(new Child__c(Parent__c = parentId));

In order to do that, you have to have the parent's Id. If your page is designed to take the Id of the parent object in the childId URL parameter, you'd use that value.

A similar change would need to be made to insertRow().

Working Minimal Example

I used the Account and Contact sObjects as an example and stripped this down to the essential functionality. I'm able to insert new child records with this page and controller.

Visualforce Page

<apex:page controller="TestQ232413Controller" >
    <apex:form >
        <apex:pageBlock >
            <apex:PageBlockTable value="{!childList}" var="int">
                <apex:facet name="footer">
                    <apex:commandLink value="Add" action="{!insertRow}"/>
                </apex:facet>
                <apex:column headerValue="FN">
                    <apex:inputField value="{!int.FirstName}"/>                                      
                </apex:column>
                <apex:column headerValue="LN">
                    <apex:inputField value="{!int.LastName}"/>                                      
                </apex:column>
            </apex:PageBlockTable>
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!insertChild}"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>

    </apex:form>
</apex:page>

Controller

public class TestQ232413Controller {
    Id parentId;
    public List<Contact> childList {get;set;}

    public TestQ232413Controller(){
        Id parentId = ApexPages.currentPage().getParameters().get('parentId');
        childList = new List<Contact>();
        childList.add(new Contact(AccountId = parentId));
    }

    public void insertChild(){
        insert childList;
    }

    public void insertRow(){
        childList.add(new Contact(AccountId = parentId));
    }
}

List Button on Contact

Content Source: URL, /apex/TestQ232413?parentId={!Account.Id}

Related Topic