One of the disadvantages comes up with Custom Page or Overriding New or Edit button with Visualforce page is its “Maintenance”, if New Filed is Added or needed to remove field we have to modify our code every time.
However, Thanks to Salesforce that we have “Field Set“.
With the Help of “Dynamic Visualforce Binding” and “Field Set” we can create effective Visualforce pages with ability to change Fields and its Sequence any time without modifying any code.
Let’s start with using Field set in Salesforce.
Step 1: Creating Field Set
First we need to create a field set. For this article, I am using custom object named “Question__c”.
We have to navigate to setting page of that object and then “Field Sets”. Create a new Field Set and add required field in Sequence as displayed in below image.
Assume that field set name is “Add_Question”.
Step 2: Use Field Set inside Visualforce using Dynamic Binding
Now, we are ready to use Field Set inside our Visualforce code. Following is code snippet of one of my Visual force page :
<apex:repeat value="{!$ObjectType.Question__c.FieldSets.Add_Question}" var="f"> <span class="label" style="align:right"> {!f.label} </span> <apex:inputField value="{!que[f.fieldPath]}" required="{!OR(f.required, f.dbrequired)}"/> </apex:repeat>
As you can see in above code snippet, Field set can be accessed inside Visualforce like “{!$ObjectType.Question__c.FieldSets.Add_Question}”.
To get label of field, simply we can use “{!f.label}”.
To check, if field is required we can use “required” or “dbrequired” property.
We are getting fields dynamically by notation “{!que[f.fieldPath]}”. Where “que” is object defined inside Apex class.
Step 3 : Using Dynamic SOQL to get value – Optional
This step is Optional. If your VF page is working in “New or Insert” mode then there is no need to populate values inside variable “que”. However what if VF page works in Edit mode? How do we know, which fields are accessed? In this case we have to use Dynamic SOQL.
First we will get list of all fields used inside Field set using below method:
/** * * Get Fields from Field Set. It is not used on VF, It used to create Dynamic SOQL for Edit mode. */ public List getFields() { return SObjectType.Question__c.FieldSets.Add_Question.getFields(); }
Now, we will try to create Dynamic SOQL which will get record on basis of Id and will be assigned to object “que”.
/** * On basis of field set, Create Dynamic SOQL */ private Question__c getQuestion_DynamiCSOQL(String quesId) { try { String query = 'SELECT '; for(Schema.FieldSetMember f : this.getFields()) { query += f.getFieldPath() + ', '; } query += 'Id, Name FROM Question__c WHERE Id = ''+quesId+'''; return Database.query(query); } catch(Exception e) { Utility.addError('There is error while Fetching existing Question using Dynamic SOQL in Field Set. Error Detail - '+e.getMessage()); //This is Utility Method to display error message on VF Page } return null; }
I hope, this article will help you. However, there are cases when you need to access Field Set even though Object name and Field Set name will be supplied dynamically.
Get Fieldset Fields in Apex dynamically when Object Name and FieldSet name is supplied at runtime
public static List readFieldSet(String fieldSetName, String ObjectName) { Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe(); Schema.SObjectType SObjectTypeObj = GlobalDescribeMap.get(ObjectName); Schema.DescribeSObjectResult DescribeSObjectResultObj = SObjectTypeObj.getDescribe(); Schema.FieldSet fieldSetObj = DescribeSObjectResultObj.FieldSets.getMap().get(fieldSetName); return fieldSetObj.getFields(); }
We can test above code in Developer Console as below:
List fieldSetMemberList = Util.readFieldSet('Account_FieldSet','Account'); for(Schema.FieldSetMember fieldSetMemberObj : fieldSetMemberList) { system.debug('API Name ====>' + fieldSetMemberObj.getFieldPath()); //api name system.debug('Label ====>' + fieldSetMemberObj.getLabel()); system.debug('Required ====>' + fieldSetMemberObj.getRequired()); system.debug('DbRequired ====>' + fieldSetMemberObj.getDbRequired()); system.debug('Type ====>' + fieldSetMemberObj.getType()); }
Leave a Reply