+ Start a Discussion
sandhubalssandhubals 

Fieldsets and VF Pages

I can't find a way to insert the field values of the parent object that are being used in the fieldset on the child object. Below is my code and I get the null values. I can only successfully insert the values in the Job object. Not sure if my approach is correct to use the parent object fields in the child fieldset.


public with sharing class fieldsetJobApplication
{
// Job object has a lookup to the Candidate object
// The fieldset is on the Job object and is referring few fields on the Candidate object
// From the VF page on insert the values into the Job object are inserted fine but the fieldset values on the Candidate object remain null

public Job__c jA {get;set;}
public Candidate__c jC {get;set;}

public fieldsetJobApplication()
{
jA = new Job__c();
jC = new Candidate__c();
}

public PageReference save()
{
assignValues();

// Insert Candidate record
insert jC;
// Provide the parent Id to child record for reference
jA.Candidate__c = jC.Id;

// All below show as null values on System.debug
System.debug('jA.Interviewer__c : ' + jA.Candidate__r.Interviewer__c);
System.debug('jA.Start_Date__c : ' + jA.Candidate__r.Start_Date__c);
System.debug('jA.Education__c : ' + jA.Candidate__r.Education__c);

System.debug('jC.Interviewer__c : ' + jC.Interviewer__c);
System.debug('jC.Start_Date__c : ' + jC.Start_Date__c);
System.debug('jC.Education__c : ' + jC.Education__c);

insert jA;

return new pagereference('/'+jA.id);
}

public List getFldsJA()
{
return SObjectType.Job__c.FieldSets.JA_Fieldset.getFields();
}
}

// VF Markup

<apex:page controller="fieldsetJobApplication">
     <apex:form >
        <apex:pageMessages />
        <apex:pageBlock title="Job Application">
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Job Application and Candidate Fields" >
                <apex:repeat value="{!FldsJA}" var="j">
                    <apex:inputField value="{!jA[j]}" />
                </apex:repeat>
            </apex:pageBlockSection>
  </apex:pageBlock>
  </apex:form>      
</apex:page>


Best Answer chosen by sandhubals
Shashikant SharmaShashikant Sharma
As I said you need to change the binding property from controller for the parent. Use this code. Its working for me.See how I have used jC and jA conditionally in the input field.

If it answers to your problem then Please mark this accepted answer so it benifits others. 
<apex:page controller="fieldsetJobApplication">
     <apex:form >
        <apex:pageMessages />
        <apex:pageBlock title="Job Application">
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Job Application and Candidate Fields" >
                <apex:repeat value="{!FldsJA}" var="j">
                    
                        <apex:inputField value="{!jA[j]}" rendered="{!IF(NOT(CONTAINS(j,'__r')), true, false)}"/>
                        <apex:inputField value="{!jC[SUBSTITUTE(j,'Candidate__r','')]}" rendered="{!IF(CONTAINS(j,'__r'), false, true)}"/>
                </apex:repeat>
            </apex:pageBlockSection>
  </apex:pageBlock>
  </apex:form>      
</apex:page>

All Answers

Shashikant SharmaShashikant Sharma
You are bindng all the fields with jA instance ,  I think inputfield could only bind with the object's field not to any related object fields. You have to bing the Candidate fields to jC instance in VFP.
sandhubalssandhubals
Thanks Shashikant for your response.
In that case the fields for the related object fields should not be contained within the fieldset of the child object. That being said, that defeats the purpose of having the relational fields (parent fields) in the child object fieldsets if we can't bind/save them from the child fieldsets using VF/Apex.
So does that mean, have the fieldset created with fields of respective object only and then bind the parent and child input object fields separately. 
 
Shashikant SharmaShashikant Sharma
As I said you need to change the binding property from controller for the parent. Use this code. Its working for me.See how I have used jC and jA conditionally in the input field.

If it answers to your problem then Please mark this accepted answer so it benifits others. 
<apex:page controller="fieldsetJobApplication">
     <apex:form >
        <apex:pageMessages />
        <apex:pageBlock title="Job Application">
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" />
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Job Application and Candidate Fields" >
                <apex:repeat value="{!FldsJA}" var="j">
                    
                        <apex:inputField value="{!jA[j]}" rendered="{!IF(NOT(CONTAINS(j,'__r')), true, false)}"/>
                        <apex:inputField value="{!jC[SUBSTITUTE(j,'Candidate__r','')]}" rendered="{!IF(CONTAINS(j,'__r'), false, true)}"/>
                </apex:repeat>
            </apex:pageBlockSection>
  </apex:pageBlock>
  </apex:form>      
</apex:page>

This was selected as the best answer
sandhubalssandhubals
It makes sense what you mentioned but for some reasons I get the error: 
Could not resolve field 'Job_Comments__c' from <apex:inputField> value binding '{!jC[SUBSTITUTE(j,'Candidate__r','')]}' in page

Job_comments__c is the field in the fieldset of the child object. Do we need to put the conditional if for the Substitute as well?
Shashikant SharmaShashikant Sharma
You need to put substitute only if parent object's field is accessed as only then you will have __r, make sure you have rendered in place for both type of input fields.  Could you post your VFP code.  
sandhubalssandhubals
<apex:page tabstyle="SFDC_Job__c" controller="fieldsetJobApplication">
     <apex:form >
        <apex:pageMessages />
        <apex:pageBlock title="Job Application">
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" />
            </apex:pageBlockButtons>
            
            <apex:pageBlockSection title="Job Application and Candidate Fields" >
                <apex:repeat value="{!FldsJA}" var="j">
                
     <apex:inputField value="{!jA[j]}" rendered="{!IF(NOT(CONTAINS(j,'__r')), true, false)}"/>
                    <apex:inputField value="{!jC[SUBSTITUTE(j,'Candidate__r','')]}" rendered="{!IF(CONTAINS(j,'__r'), false, true)}"/>
                </apex:repeat>
            </apex:pageBlockSection>
  </apex:pageBlock>
  </apex:form>      
</apex:page>
sandhubalssandhubals
public with sharing class fieldsetJobApplication
{
public SFDC_Job__c jA {get;set;}
    public SFDC_Candidate__c jC {get;set;}
   
    public fieldsetJobApplication()
    {
     jA = new SFDC_Job__c();
     jC = new SFDC_Candidate__c();


    }

    public List<Schema.FieldSetMember> getFldsJA()
    {
        return SObjectType.SFDC_Job__c.FieldSets.JA_Fieldset.getFields();
    }

public PageReference save()
    {
   
  insert jC;
        jA.Candidate__c = jC.Id;
       
      
        insert jA;
       
        return new pagereference('/'+jA.id);
    }
   
}
sandhubalssandhubals
I also tried the below instead but no luck
<apex:inputField value="{!jC[IF(CONTAINS(j,'__r'), SUBSTITUTE(j,'SFDC_Candidate__r.',''), j)]}" rendered="{!IF(CONTAINS(j,'__r'), false, true)}"/>
API Names for Candidate and Job are:
SFDC_Candidate__c
SFDC_Job__c
Shashikant SharmaShashikant Sharma
Most likely it should be somethhing like API Name of reference to Candidate + __r . Ideally you should print the field set field values and check what are coming from field set ad substitute accordingly.

Use apex:outputField in VFP to see the values and then substitute accordingly.
sandhubalssandhubals
Thanks Shashikant, finally worked, 1) I wasn't using the rendered true and false properly. 2) I should have been looking at the field API name not the field API name in the SUBSTITUTE function. Figured that out after System.debug:
public with sharing class fieldsetJobApplication 
{
	public SFDC_Job__c jA {get;set;}
    public SFDC_Candidate__c jC {get;set;}
    
    public fieldsetJobApplication()
    {
    	jA = new SFDC_Job__c();
    	jC = new SFDC_Candidate__c();
    }

    public List<Schema.FieldSetMember> getFldsJA() 
    {
    	list<Schema.FieldSetMember> fsFieldsList = new list<Schema.FieldSetMember>();
    	fsFieldsList = SObjectType.SFDC_Job__c.FieldSets.JA_Fieldset.getFields(); 
    	
    	for(integer i=0;i<fsFieldsList.size();i++)
        {
            String fldName;
            fldName = fsFieldsList[i].getFieldPath();
    	
    		System.debug('$$$ fldName : ' + fldName);
        }
    	
    	return fsFieldsList;
        //return SObjectType.SFDC_Job__c.FieldSets.JA_Fieldset.getFields(); 
    }

	public PageReference save()
    {
		insert jC;
        jA.Candidate__c = jC.Id;

        insert jA;
        
        return new pagereference('/'+jA.id);
    }
}


<apex:page tabstyle="SFDC_Job__c" controller="fieldsetJobApplication">
	    <apex:form > 
        <apex:pageMessages />
        <apex:pageBlock title="Job Application"> 
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" /> 
            </apex:pageBlockButtons>
             
            <apex:pageBlockSection title="Job Application and Candidate Fields" >
                <apex:repeat value="{!FldsJA}" var="j">
                	<apex:inputField value="{!jA[j]}" rendered="{!IF(NOT(CONTAINS(j,'__r')), true, false)}"/>
                    <apex:inputField value="{!jC[IF(CONTAINS(j,'__r'), SUBSTITUTE(j,'Candidate__r.',''), j)]}" rendered="{!IF(CONTAINS(j,'__r'), true, false)}"/> 
                    
                </apex:repeat>
            </apex:pageBlockSection>
		</apex:pageBlock>
		</apex:form>       
</apex:page>



Shashikant SharmaShashikant Sharma
Glad to hear It worked for you :) 
Ruchika ChoudharyRuchika Choudhary
What if I need multiple candidate__c ?