+ Start a Discussion
neckrneckr 

Nested child records within its associated Parent Records in Visual Force?

Hi, I could use some help trying to figure out how to render mutiple child records within is associated parent record pagesection within a pageblock.

 

In one VF page I would like to render multiple Con_Service_Task_Request__c record fields and its associated Customer_Reference_Report__c fields.  There are 3 Customer_Reference_Report__c child records for every Con_Service_Task_Request__c master record, and multiple  Con_Service_Task_Request__c records for each account.

 

I have started by getting the list of Con_Service_Task_Request__c records and list of Customer_Reference_Report__c for the associated account, however I am having trouble with the idea of linking the two together so that the associated child records only show with its parent.  My reading tells me that I may need to use Maps, however not sure where to start and would appreciate some gudiance.  Here is the snippet of my page and controller.

 

 

<apex:pageBlock mode="mainDetail" id="ServiceTaskDetails" >         
<apex:pageBlockButtons location="top">               
<apex:commandButton action="{!save}" value="Save" />                          
</apex:pageBlockButtons>
                   
<apex:repeat value="{!ST}" var="STasks" >  
<apex:pageBlockSection columns="3"  title="Service Task Verification Details: {!STasks.Service_Code__c}" collapsible="true" id="STList" >                    

<apex:inputField value="{!STasks.Associated_License__c}" rendered="{!STasks.LV_Required_Code__c==0}"/>
<apex:inputField value="{!STasks.Associated_Insurance_Policy__c}" rendered="{!STasks.GLIV_Required_Code__c==0}"/>
<apex:inputField value="{!STasks.Associated_Eco_Accreditation__c}" rendered="{!STasks.EFAV_Required_Code__c==0}"/>
<apex:inputhidden rendered="{!STasks.LV_Required_Code__c==1}"/>
<apex:inputhidden rendered="{!STasks.GLIV_Required_Code__c==1}"/>
<apex:inputhidden rendered="{!STasks.EFAV_Required_Code__c==1}"/>


<apex:repeat value="{!custrefs}" var="CRV" >  

<apex:inputField value="{!CRV.CRV_Contact__r.Company_Name__c}" rendered="{!CRV.CRV_Service__r.Service__r.For_Business__c}" />
<apex:inputField value="{!CRV.CRV_Contact__r.FirstName}" /> 
<apex:inputField value="{!CRV.CRV_Contact__r.LastName}" />
<apex:inputField value="{!CRV.CRV_Contact__r.Email}" />
<apex:inputField value="{!CRV.CRV_Contact__r.Phone}" />   
<apex:inputField value="{!CRV.CRV_Service_Date__c}" />
<apex:inputHidden />
  
                 
</apex:repeat> 
                            
</apex:pageBlockSection>                        
 </apex:repeat>
            
</apex:pageblock>

 

//----------------------------SERVICE TASKS METHOD--------------------------------------->
     
      public List<Con_Service_Task_Request__c> getST()     
       {        
         if ( (null!=getAccount().id) && (ST == null) )
              
       {            
        ST=[SELECT Id, Account__c, Service_Code__c, Associated_Eco_Accreditation__c,Associated_Insurance_Policy__c, Associated_License__c, LV_Required_Code__c, GLIV_Required_Code__c, EFAV_Required_Code__c                          
        FROM Con_Service_Task_Request__c                           
        WHERE Account__c = : getAccount().ID                          
        ORDER BY Service_Code__c];
          }

                                                   
        return ST;   
       }         
       
                     
//----------------------------CUSTOMER REFERENCES METHOD----------------------------------->
     
      public List<Customer_Reference_Report__c> getcustrefs()     
       {        
         if ( (null!=getAccount().id) && (custrefs == null) )
              
       {            
        custrefs=[SELECT Id, CRV_Account__c, CRV_Contact__r.ID, CRV_Contact__r.Company_Name__c, CRV_Contact__r.Email, CRV_Contact__r.Phone, CRV_Contact__r.LastName,CRV_Contact__r.FirstName, CRV_Service_Performed__c, CRV_Service_Date__c, CRV_Service__r.Service__r.For_Business__c                           
        FROM Customer_Reference_Report__c                           
        WHERE CRV_Account__c = : getAccount().ID                          
        ORDER BY CRV_Service_Performed__c];
          }
            CustomerReferenceContact = new List<Contact>(); 
            for (Customer_Reference_Report__c CRV : custrefs) {
                CustomerReferenceContact.add(CRV.CRV_Contact__r );
}

                                                   
        return custrefs;   
       }     

 

 

 

 

 

Shashikant SharmaShashikant Sharma

Hi neckr,

 

Create a map in controller class : Key as Con_Service_Task_Request__c record's ID and Value as List<Customer_Reference_Report__c >

 

Map<ID , List<Customer_Reference_Report__c >> mapST_Cusrefs = new Map<ID , List<Customer_Reference_Report__c >>();

 

Fill this map in controller class with appropriate values. If any Con_Service_Task_Request__c record does not have List<Customer_Reference_Report__c > then add a empty list in map for that, so that key not find issue does not come.

 

In VFP in second repeat control

 

<apex:repeat value="{!custrefs}" var="CRV" >  change this to 

 

<apex:repeat value="{!mapST_Cusrefs[STasks.id]}" var="CRV" > 

 

neckrneckr

I declared this in my class

 

Public Map<ID, List<Customer_Reference_Report__c >> mapST_Cusrefs = new Map<ID, List<Customer_Reference_Report__c >>(); 

 

I wrote the code below, I assume I did the assignment properly? 

 

However when using !mapST_Cusrefs in the Page its not says unknown property, my though is that its not a method.

 

I tried creating the map in a method form using getmapST_Cusrefs but didnt get far with that.  Any suggestions?

 

 

public List<Con_Service_Task_Request__c> getST()     
       {        
         if ( (null!=getAccount().id) && (ST == null) )
              
       {            
        ST=[SELECT Id, Account__c, Service_Code__c, Associated_Eco_Accreditation__c,Associated_Insurance_Policy__c, Associated_License__c, LV_Required_Code__c, GLIV_Required_Code__c, EFAV_Required_Code__c                          
        FROM Con_Service_Task_Request__c                           
        WHERE Account__c = : getAccount().ID                          
        ORDER BY Service_Code__c];
          }
        
        for(Con_Service_Task_Request__c STasks : ST){
        
        custrefs = [SELECT Id, CRV_Account__c, CRV_Contact__r.ID, CRV_Contact__r.Company_Name__c, CRV_Contact__r.Email, CRV_Contact__r.Phone, CRV_Contact__r.LastName,CRV_Contact__r.FirstName, CRV_Service_Performed__c, CRV_Service_Date__c, CRV_Service__r.Service__r.For_Business__c                           
        FROM Customer_Reference_Report__c                           
        WHERE CRV_Service__c = :STasks.ID                         
        ORDER BY CRV_Service_Performed__c];
        
        if(custrefs==null){
        mapST_Cusrefs.put(STasks.ID, new List<Customer_Reference_Report__c>());
        }
                   mapST_Cusrefs.put(STasks.ID, custrefs);
           
        
          }    
       
                                                   
        return ST;  
//How do I return mapST_Cusrefs to be used in the VFP?
}

 

 

 

Shashikant SharmaShashikant Sharma

 

Public Map<ID, List<Customer_Reference_Report__c >> mapST_Cusrefs = new Map<ID,

List<Customer_Reference_Report__c >>(); 

 

Use this instead of above 

public Map<ID, List<Customer_Reference_Report__c >> mapST_Cusrefs

{

    get

    {

       if(mapST_Cusrefs == null)

       {

mapST_Cusrefs= new Map<ID, List<Customer_Reference_Report__c >>();   

       }

       return mapST_Cusrefs;

    }

   set;

 

}

 

Even though your code will work with above change but you need to optimize your code also.

neckrneckr

I made the changes however its not liking the suggested VF page code

 

<apex:repeat value="{!mapST_Cusrefs[STasks.id]}" var="CRV" >

<apex:inputField value="{!CRV.CRV_Contact__r.FirstName}" />

 

Error: Could not resolve the entity from <apex:inputField> value binding '{!CRV.CRV_Contact__r.Company_Name__c}'. inputField can only be used with SObject fields.

 

The pages developers guide says I need the following type of notation

 

<apex:inputField value="{!mapST_Cusrefs[CRV].CRV_Contact__r.FirstName}" />

 

I tested and it compiles, however it does't make sense since it will be looking for a key thats not in my map.

 

Any suggestions?

 

 

Also what do you mean by optimizing my code,  I loosely grasp the concept of bulkifying for triggers but what is meant my optimizing for the controller?

Shashikant SharmaShashikant Sharma

The error that you are facing is because you are trying to bind a related objects field in input field and it is not allowed.

If you want inline editing like this you have to create another Map

//CRV ID As key and Contact record as value

MAP<ID , Contact> mapCRV_ID_Contact = new MAP<ID , Contact>();

 

Do this in VFP

 

<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].FirstName}" />

 Similar for All contact fields 

 

Create MAP for other related object and apply same in vfp for their fields.

 

 

 

neckrneckr

Thanks, I got the related object fields to render and save properly, but still having issues with the syntax for direct object fields. I can get <apex:inputField value="{!mapST_Cusrefs[STasks.ID][0].CRV_Service_Date__c}" /> to render and save properly, so I dont think its my controller and just an issue with the way VFP is reading the syntax.  Any suggestions?

 

 

<apex:repeat value="{!mapST_Cusrefs[STasks.ID]}" var="CRV" > 
 

<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].Company_Name__c}" /> <!-- rendered="{!CRV.CRV_Service__r.Service__r.For_Business__c}" /> -->
<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].FirstName}" />
<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].LastName}" />
<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].Email}" />
<apex:inputField value="{!mapCRV_ID_Contact[CRV.id].Phone}" />
<!--<apex:inputField value="{!CRV.CRV_Service_Date__c}" />--> Error:: Could not resolve the entity from <apex:inputField> value 
binding '{!CRV.CRV_Service_Date__c}'. inputField can only be used with 
SObject fields.

 

 

Shashikant SharmaShashikant Sharma

Again I would suggest you to add a 

 

Map<ID , Customer_Reference_Report__c> mapCRVID_CRV = new MAP<ID , Customer_Reference_Report__c>();

 

 

 

In VFP use

 

<apex:inputField value="{!CRVID_CRV[CRV.id].CRV_Service_Date__c}" />