[SalesForce] Nested Tables – How to Add A Child Row Dynamically

Working on Nested Table Functionality, I was able to display the Master-Detail custom objects Master__c and Child__c in a Nested Table. Now, I need to add row/delete functionality for the Child Table.Where i need a Master Object id to perform inserts and updates.

Any Idea on how to get the Master object id so that I can Add/delete a row dynamically for the child object.

Sample VF looks like:
enter image description here

Please Suggest.
Thanks in advance

Here is my code

<apex:PageBlockSection title="Set Schedules" id="schedules" columns="1">
    <apex:pageBlock >
        <apex:variable var="rowNumber" value="{!0}"/>
        <apex:variable var="subrow" value="{!0}"/>   
        <apex:pageBlocktable value="{!oliEdit}" var="e" columnsWidth="25%25%45%5%">
        <apex:column headerValue="SNo."><apex:outputText value="{0}" > <apex:param value="{!rowNumber+1}" /> </apex:outputText></apex:column>
        <apex:column headervalue="Product Name"><apex:outputField value="{!e.Product__c}" style="font-weight:bold"/></apex:column>
        <apex:column headervalue="Amount"><apex:outputField value="{!e.Sales_Price__c}" style="font-weight:bold"/></apex:column>
        <apex:column headervalue="Start Date"><apex:outputfield value="{!e.ServiceDate__c}" style="font-weight:bold"/></apex:column>
        <apex:column headervalue="Number of Months"><apex:outputfield value="{!e.Number_of_Installments__c}" style="font-weight:bold"/></apex:column>                       
        <!--apex:column><apex:outputLink  Value ="/apex/OliWizard5?Id ={!e.Id}" target="_top">Edit Schedules</apex:outputLink> </apex:column-->
        <apex:column breakBefore="true" colspan="5">
            <apex:pageBlock title="Schedules for {!e.id}" id="pb">
            <apex:pageBlocktable value="{!oliSchEdit}" var="s" columnsWidth="25%25%25%25%" >
                            <apex:column headerValue="SNo." rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}"><apex:outputText value="{0}" > <apex:param value="{!subrow+1}" /> </apex:outputText></apex:column>
                            <apex:column headerValue="Opportunity Product" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}" > <apex:outputfield value="{!s.Opportunity_Product__c}" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}"/></apex:column>
                            <apex:column headerValue="Amount" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}" ><apex:inputfield value="{!s.Amount__c}" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}"/></apex:column>    
                            <apex:column headerValue="Date" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}" ><apex:inputfield value="{!s.Date__c}" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}"/></apex:column>    
                            <apex:column headerValue="Action" rendered="{!IF((s.Opportunity_Product__c ==  e.id),true,false)}"  >
                                 <apex:commandButton value="Delete" action="{!deleteRow}"> 
                                 <apex:param name="rowIndex" value="{!subrow}"/>
                                 </apex:commandButton>
                                 <apex:variable var="subrow" value="{!subrow+1}"/>
                            </apex:column> 
                  </apex:pageBlocktable>
            <apex:variable var="rowNumber" value="{!rowNumber+1}"/>
            <apex:commandButton value="Add Schedule" action="{!addRow}" reRender="pb"><apex:param name="rIndex" value="{!e.id}"/></apex:commandButton>
                </apex:pageBlock>
         </apex:column>

     </apex:pageBlocktable> 
        </apex:pageBlock>
   </apex:PageBlockSection>       
</apex:PageBlock>

Controller class: This is relavent code related to this VF page.
public without sharing class OliWizardExt
{
Opportunity_Product__c oli;
Opportunity opp;
Id thisOpportunityId;
public Integer rowIndex{get;set;}
public Integer totalcount{get;set;}
List saveOliList;
List oliEdit = new List();
List oliSchEdit = new List();
List deleteSchedule = new List();
public Opportunity_Product_Schedule__c del;
public List deleteops{get;set;}
public List addops{get;set;}
integer i;
integer j;

set<id> tids = new set<id>();

public OliWizardExt(ApexPages.StandardController con)
{

    onLoad();
}

 public PageReference deleteRow(){
    rowIndex = Integer.valueOf(ApexPages.currentPage().getParameters().get('rowIndex'));
    del = oliSchEdit.remove(rowIndex);
    deleteops.add(del); 
     delete deleteops;
     return null;
}
public void addRow(){
    addops = new List<Opportunity_Product_Schedule__c>();
    thisOppProductId = ApexPages.currentPage().getParameters().get('rIndex');
    Opportunity_Product__c oppc= [Select Id,
                                  Name,
                                  Product__c,
                                  Sales_Price__c,
                                  ServiceDate__c,
                                  Start_Period__c,
                                  Number_of_Installments__c 
                                  from Opportunity_Product__c where id =: thisOppProductId];
     addops.add(new Opportunity_Product_Schedule__c (Opportunity_Product__c= oppc.Id,Amount__c=0.0,Product__c = oppc.Product__c,Start_Period__c =oppc.Start_Period__c));
    upsert addops;



}

    //saveOliList holds Opportunity_Product__c ids-----
    for(Opportunity_Product__c oc: saveOliList){
            tids.add(oc.id);
        }
        oliQuery();
    addops = new List<Opportunity_Product_Schedule__c>();
    deleteops = new List<Opportunity_Product_Schedule__c>();
        return new PageReference('/apex/OliWizard5');

}

public PageReference backToOpp()
{   
   update oliSchEdit;  
   return new PageReference('/'+thisOpportunityId);
}
public PageReference btnAdd(){

   Opportunity_Product_Schedule__c opscc = new Opportunity_Product_Schedule__c();
      //opscc.Opportunity_Product__c = 
    opscc.Number_of_Installments__c =1.0;
    opscc.Amount__c =0.00;
    insert opscc;
    oliQuery();
    return new PageReference('/apex/OliWizard4');
}
public void oliQuery(){
    oliEdit =[Select Id,
              Name,
              Product__c,
              Sales_Price__c,
              ServiceDate__c,
              Number_of_Installments__c
              from Opportunity_Product__c 
              where id =: tids];
    oliSchEdit=[Select Id,
                Opportunity_Product__c,
                Amount__c,
                Date__c,
                Number_of_Installments__c,
                Start_Period__c,
                Product_Name__c  
                from Opportunity_Product_Schedule__c 
                where Opportunity_Product__c=:oliEdit 
                order by Opportunity_Product__c,Date__c];
    totalcount = oliSchEdit.size();
}

public List<Opportunity_Product__c> getOliEdit()
{
    return oliEdit;
}
public List<Opportunity_Product_Schedule__c> getOliSchEdit(){
    return olischEdit;
}

}

Best Answer

If you can post your code it would be helpful.

Here are my assumptions and solution

  1. Lets consider you are using List<record> lstrec and iterating this list to create a row in your Visualforce page.

  2. On click of button "Add Schedule" call method addrow() in controller.

  3. In this method create new instance of record/object, Visualforce will automatically add row.

As per your code, you need to have addRow() method something like this -

public void addRow(){ 
    thisOppProductId = ApexPages.currentPage().getParameters().get('rIndex');
    Opportunity_Product__c oppc= [Select Id,
                                  Name,
                                  Product__c,
                                  Sales_Price__c,
                                  ServiceDate__c,
                                  Start_Period__c,
                                  Number_of_Installments__c 
                                  from Opportunity_Product__c where id =: thisOppProductId];
    if(oliSchEdit != null)
    {
        oliSchEdit.add(new Opportunity_Product_Schedule__c (Opportunity_Product__c= oppc.Id,Amount__c=0.0,Product__c = oppc.Product__c,Start_Period__c =oppc.Start_Period__c));
    } 
}

I am not sure what is meaning of parameter rIndex , just copied it from your code.