You need to sign in to do that
Don't have an account?
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; }
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" >
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 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.
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?
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
Similar for All contact fields
Create MAP for other related object and apply same in vfp for their fields.
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?
Again I would suggest you to add a
In VFP use