Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Please have a look at these 2 code snippets:

(1)

<apex:page id="pageId" standardcontroller="My_Object__c"> 
<apex:form id="formId"> 
    <apex:pageblock id="pbId"> 
        <apex:pageblocksection columns="1" id="pbsIs"> 
            <apex:repeat value="{!$ObjectType.My_Object__c.FieldSets.MyFieldSet}" var="f"> 
                <apex:inputfield value="{!My_Object__c[f]}"> 
            </apex:inputfield></apex:repeat> 
        </apex:pageblocksection> 
    </apex:pageblock> 
</apex:form> 
</apex:page>

(2)

<apex:pageBlockSection title="Dimensions">
    <apex:repeat value="{!fields}" var="f">
        <apex:inputField value="{!merch[f.fieldPath]}"  required=" 
                 {!OR(f.required, f.dbrequired)}"/>
    </apex:repeat>
</apex:pageBlockSection>

I have following doubts about it:

  1. In (1) <apex:repeat var="f" is an object that is holding reference of current object
    then what is the meaning of writing value="{!My_Object__c[f]}" ? what will
    !My_Object__c[f] return?
  2. In (2) what is the meaning of "{!merch[f.fieldPath]}" statement?

I would be very grateful if someone can explain better how this fieldset works in salesforce.

share|improve this question

2 Answers 2

up vote 8 down vote accepted

Long introduction talk

This would probably be much easier for you if you have ever played with "Dynamic Apex" and "Dynamic SOQL". Sometimes we need to work on the level of generic sObjects rather than concrete Account, User or Custom_Object__crecords.

Maybe running this in Execute Anonymous will help:

Map<String, Schema.SObjectField> M = Schema.SObjectType.Account.fields.getMap();
List<String> allFieldNames = new List<String>();
allFieldNames.addAll(m.keyset());
System.debug(allFieldNames);

SObject obj = Database.query('SELECT ' + String.join(allFieldNames,',') + ' FROM Account LIMIT 1');

for(String fieldName : allFieldNames){
    System.debug('Account.' + fieldName + ' = ' + obj.get(fieldName));
}

So there are ways to refer dynamically, acc.get('AccountNumber') instead of acc.AccountNumber (but then it's up to you to use info from describe() and cast it properly to a number, string or date field for example). Scenarios when this might be needed vary (managed packages code that has to dynamically check if fields are present on the object and standard way won't compile; letting user select the fields he'd like to see etc).

Back to fieldsets

In (1) f will be a Schema.FieldSetMember variable holding the field name that can be used in dynamic getter like in the Apex example above. We just benefit from the fact that their toString() method returns String with the field name, same as getFieldPath() does.

So {!f} gives you the field API name, same as {!f.fieldPath} (the "get" word is omitted because that's the convention of visualforce getters/setters). You can use the info from the link to construct other merge fields like {!f.label} or {!f.required}.

I confess I'm lazy and always just use "f" instead of "f.fieldPath" ;) But it can be viewed as kind of against best practices. Code with just "f" all over the place will break as soon as Salesforce decides to change the Schema.FieldSetMember.toString().

share|improve this answer
    
Thanks @eyescream for such a detailed explanation. –  Pramod Kumar Dec 2 '12 at 4:45

Well they are both same. Have you tried doing {!f} in the visualforce page? This will give you the API name of the field in the fieldset i.e. the fieldpath.

And also when you are doing this {!$ObjectType.My_Object__c.FieldSets.MyFieldSet} you are actually describing the fieldset and is equivalent to something like this in apex :

List<Schema.FieldSetMember> fields = 
    Schema.SObjectType.My_Object__c.fieldSets.getMap().get('MyFieldSet').getFields();

By doing {!My_Object__c[f]} this you are actually passing the fieldtoken to the sobject.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.