Newer Version Available
Creating and Displaying Dynamic Components
There are two parts to embedding dynamic Visualforce components on your page:
- Adding an <apex:dynamicComponent> tag somewhere on your page. This tag acts as a placeholder for your dynamic component.
- Developing a dynamic Visualforce component in your controller or controller extension.
1<apex:page standardController="Contact" extensions="DynamicComponentExample">
2 <apex:dynamicComponent componentValue="{!headerWithDueDateCheck}"/>
3 <apex:form>
4 <apex:inputField value="{!Contact.LastName}"/>
5 <apex:commandButton value="Save" action="{!save}"/>
6 </apex:form>
7</apex:page>1public class DynamicComponentExample {
2 public DynamicComponentExample(ApexPages.StandardController con) { }
3 public Component.Apex.SectionHeader getHeaderWithDueDateCheck() {
4 date dueDate = date.newInstance(2011, 7, 4);
5 boolean overdue = date.today().daysBetween(dueDate) < 0;
6
7 Component.Apex.SectionHeader sectionHeader = new Component.Apex.SectionHeader();
8 if (overdue) {
9 sectionHeader.title = 'This Form Was Due On ' + dueDate.format() + '!';
10 return sectionHeader;
11 } else {
12 sectionHeader.title = 'Form Submission';
13 return sectionHeader;
14 }
15 }
16}Each dynamic component has access to a common set of methods and properties. You can review this list in the Apex Developer's Guide in the chapter titled “Component Class.”.
Dynamic Custom Components
1Component.c.MyCustomComponent myDy = new Component.c.MyCustomComponent();1Component.MyCustomComponent myDy = new Component.MyCustomComponent();1Component.TheirName.UsefulComponent usefulC = new Component.TheirName.UsefulComponent();Passing Attributes through the Constructor
1Component.Apex.DataList dynDataList =
2 new Component.Apex.DataList(id='myDataList', rendered=true);There are two components that must have an attribute defined in the constructor, rather than through a property:
- Component.Apex.Detail must have showChatter=true passed to its constructor if you want to display the Chatter information and controls for a record. Otherwise, this attribute is always false.
- Component.Apex.SelectList must have multiSelect=true passed to its constructor if you want the user to be able to select more than one option at a time. Otherwise, this value is always false.
These values are Booleans, not Strings; you don’t need to enclose them in single quote marks.
Defining Expressions and Arbitrary HTML
1Component.Apex.Detail detail = new Component.Apex.Detail();
2detail.expressions.subject = '{!Account.ownerId}';
3detail.relatedList = false;
4detail.title = false;1Component.Apex.OutputText head1 = new Component.Apex.OutputText();
2head1.expressions.value =
3 '{!IF(CONTAINS($User.FirstName, "John"), "Hello John", "Hey, you!")}';Passing in values through expressions is valid only for attributes that support them. Using {! } outside of the expressions property will be interpreted literally, not as an expression.
1Component.Apex.OutputText head1 = new Component.Apex.OutputText();
2head1.escape = false;
3head1.value = '<h1>This header contains HTML</h1>';Defining Facets
1Component.Apex.DataTable myTable = new Component.Apex.DataTable(var='item');
2myTable.expressions.value = '{!items}';
3Component.Apex.OutputText header =
4 new Component.Apex.OutputText(value='This is My Header');
5myTable.facets.header = header;For more information on facets, see Best Practices for Using Component Facets.
Defining Child Nodes
You can add child nodes to a dynamic Visualforce component using the childComponents property. The childComponents property acts as a reference to a List of Component.Apex objects.
1public Component.Apex.PageBlock getDynamicForm() {
2 Component.Apex.PageBlock dynPageBlock = new Component.Apex.PageBlock();
3
4 // Create an input field for Account Name
5 Component.Apex.InputField theNameField = new Component.Apex.InputField();
6 theNameField.expressions.value = '{!Account.Name}';
7 theNameField.id = 'theName';
8 Component.Apex.OutputLabel theNameLabel = new Component.Apex.OutputLabel();
9 theNameLabel.value = 'Rename Account?';
10 theNameLabel.for = 'theName';
11
12 // Create an input field for Account Number
13 Component.Apex.InputField theAccountNumberField = new Component.Apex.InputField();
14 theAccountNumberField.expressions.value = '{!Account.AccountNumber}';
15 theAccountNumberField.id = 'theAccountNumber';
16 Component.Apex.OutputLabel theAccountNumberLabel = new Component.Apex.OutputLabel();
17 theAccountNumberLabel.value = 'Change Account #?';
18 theAccountNumberLabel.for = 'theAccountNumber';
19
20 // Create a button to submit the form
21 Component.Apex.CommandButton saveButton = new Component.Apex.CommandButton();
22 saveButton.value = 'Save';
23 saveButton.expressions.action = '{!Save}';
24
25 // Assemble the form components
26 dynPageBlock.childComponents.add(theNameLabel);
27 dynPageBlock.childComponents.add(theNameField);
28 dynPageBlock.childComponents.add(theAccountNumberLabel);
29 dynPageBlock.childComponents.add(theAccountNumberField);
30 dynPageBlock.childComponents.add(saveButton);
31
32 return dynPageBlock;
33}1<apex:form>
2 <apex:dynamicComponent componentValue="{!dynamicForm}"/>
3</apex:form>1<apex:form>
2 <apex:pageBlock>
3 <apex:outputLabel for="theName"/>
4 <apex:inputField value="{!Account.Name}" id="theName"/>
5 <apex:outputLabel for="theAccountNumber"/>
6 <apex:inputField value="{!Account.AccountNumber}" id="theAccountNumber"/>
7 <apex:commandButton value="Save" action="{!save}"/>
8 </apex:pageBlock>
9</apex:form>