expert photo

James Deboe

Declarative Visualforce

While SFDC developers should always use standard functionality whenever possible it’s inevitable that certain requirements will need to be implemented using custom code constructs such as APEX and Visualforce. This post will show an example of bridging the gap between meeting requirements that require custom coding while still allowing a certain level of declarative administration.

The high level requirements for this example are as follows:

  • A Custom object that holds meta-data associated to Content documents
  • The ability to search for documents based on one or more fields from custom object
  • Display certain meta-data fields and link to Content document in results

Of course, an SFDC developer could hard code the search and result fields in an apex:form in a Visualforce page, but for our purposes we want to empower the SFDC administrator to declaratively add/remove fields to or from both sets of fields. The question is how do we achieve the declarative nature we seek within APEX and Visualforce?

Part of the answer is using field sets.

Field Sets in SFDC allow an admin to add/remove fields in declarative fashion as part of the object configuration. The field set is created as part of object configuration and then fields are added to the field set much the same way fields are added to standard page layouts.

Step 1: Create the Field Set

Step 2: Add fields to the fields set.

Now that the field sets have been created, in our case we need two, one for the search fields on the form and another for the fields to display in the results panel returned from the search.

That’s the easy part, now we need to reference the field sets in our APEX controller and bind the fields to the Visualforce page.

I wrote a generic convenience method in a util class that takes an SObject name and the name of the field set and returns a list of FieldSetMember objects. The method uses Schema.getGlobalDescribe() and other Schema methods to describe the object passed and subsequently return the fieldset by name.

public static List<Schema.FieldSetMember> getFieldSetByObjectAndName(String objectName, String fieldSetName) {

Map<String, Schema.SObjectType> globalDescribeMap = Schema.getGlobalDescribe();
Schema.SObjectType sObjectType = globalDescribeMap.get(objectName);
Schema.DescribeSObjectResult describeSObjectResult = sObjectType.getDescribe();
Schema.FieldSet fieldSet = describeSObjectResult.FieldSets.getMap().get(fieldSetName);

return fieldSet.getFields();

Now I reference the previous method in our controller so we can bind the fields to the Visualforce page.

public List<Schema.FieldSetMember> searchFields {get;set;}
searchFields = SearchUtil.getFieldSetByObjectAndName(‘Search_Meta_Data__c’, ‘Search_Fields’);

The fields can now be bound to the Visualforce page as follows:

<apex:form >
<apex:pageBlock title=“Search Fields”>
<apex:pageBlockSection title=“Search Fields” id=“searchFieldsPanel”>
<apex:repeat value=”{!searchFields}” var=“f”>
<apex:inputField value=”{!searchObject[f.fieldPath]}” />
<apex:pageBlockButtons >
<apex:commandButton action=”{!search}” value=“Search” id=“searchAction”/>

Notice that the collection being iterated is searchFields and the binding object is searchObject which is important given that the fields in the apex:form must be bound to an SObject. Be sure to initialize searchObject in your controller or you’ll get an error.

Now you can add and remove fields in the field set and see how the Visualforce page changes. The fields will also display in the same order that they are arranged in the field set, giving declarative control over the order that fields display as well.

That’s it for this post. In my next post I’ll talk about iterating the search results and displaying them in the page with dynamic columns driven from another field set.

Posted in: Salesforce