Dynamic Visualforce components are best used when you don’t know the type of object you want to reference, as opposed to dynamic Visualforce bindings, which are best used when you don’t know the fields you want to access.
The following scenario for using dynamic Visualforce constructs a simple, reusable page with a known set of fields you want to access. The page and its custom object are placed into an unmanaged package and distributed throughout the same organization.
public class DynamicClassroomList { private ApexPages.StandardSetController controller; private PageReference savePage; private Set<String> unSelectedNames; private Set<String> selectedNames; public List<String> selected { get; set; } public List<String> unselected { get; set; } public String objId { get; set; } public List<String> displayObjs { get; private set; } boolean idIsSet = false; public DynamicClassroomList() { init(); } public DynamicClassroomList(ApexPages.StandardSetController con) { this.controller = con; init(); } private void init() { savePage = null; unSelectedNames = new Set<String>(); selectedNames = new Set<String>(); if (idIsSet) { ApexPages.CurrentPage().getParameters().put('id', objId); idIsSet = false; } } public PageReference show() { savePage = Page.dynVFClassroom; savePage.getParameters().put('id', objId); return savePage; } public List<SelectOption> displayObjsList { get { List<SelectOption> options = new List<SelectOption>(); List<Classroom__c> classrooms = [SELECT id, name FROM Classroom__c]; for (Classroom__c c: classrooms) { options.add(new SelectOption(c.id, c.name)); } return options; } } public PageReference customize() { savePage = ApexPages.CurrentPage(); savePage.getParameters().put('id', objId); return Page.dynamicclassroomlist; } // The methods below are for constructing the select list public List<SelectOption> selectedOptions { get { List<String> sorted = new List<String>(selectedNames); sorted.sort(); List<SelectOption> options = new List<SelectOption>(); for (String s: sorted) { options.add(new SelectOption(s, s)); } return options; } } public List<SelectOption> unSelectedOptions { get { Schema.DescribeSObjectResult R = Classroom__c.SObjectType.getDescribe(); List<Schema.ChildRelationship> C = R.getChildRelationships(); List<SelectOption> options = new List<SelectOption>(); for (Schema.ChildRelationship cr: C) { String relName = cr.getRelationshipName(); // We're only interested in custom relationships if (relName != null && relName.contains('__r')) { options.add(new SelectOption(relName, relName)); } } return options; } } public void doSelect() { for (String s: selected) { selectedNames.add(s); unselectedNames.remove(s); } } public void doUnSelect() { for (String s: unselected) { unSelectedNames.add(s); selectedNames.remove(s); } } public Component.Apex.OutputPanel getClassroomRelatedLists() { Component.Apex.OutputPanel dynOutPanel= new Component.Apex.OutputPanel(); for(String id: selectedNames) { Component.Apex.RelatedList dynRelList = new Component.Apex.RelatedList(); dynRelList.list = id; dynOutPanel.childComponents.add(dynRelList); } return dynOutPanel; } }
<apex:page standardController="Classroom__c" recordSetVar="classlist" extensions="DynamicClassroomList"> <apex:dynamicComponent componentValue="{!ClassroomRelatedLists}"/> <apex:form> <apex:pageBlock title="Classrooms Available" mode="edit"> <apex:pageMessages/> <apex:selectRadio value="{!objId}"> <apex:selectOptions value="{!displayObjsList}"/> </apex:selectRadio> </apex:pageBlock> <apex:commandButton value="Select Related Items" action="{!Customize}"/> </apex:form> </apex:page>
<apex:page standardController="Classroom__c" recordsetvar="listPageMarker" extensions="DynamicClassroomList"> <apex:messages/><br/> <apex:form> <apex:pageBlock title="Select Relationships to Display" id="selectionBlock"> <apex:panelGrid columns="3"> <apex:selectList id="unselected_list" required="false" value="{!selected}" multiselect="true" size="20" style="width:250px"> <apex:selectOptions value="{!unSelectedOptions}"/> </apex:selectList> <apex:panelGroup> <apex:commandButton value=">>" action="{!DoSelect}" reRender="selectionBlock"/> <br/> <apex:commandButton value="<<" action="{!DoUnselect}" reRender="selectionBlock"/> </apex:panelGroup> <apex:selectList id="selected_list" required="false" value="{!unselected}" multiselect="true" size="20" style="width:250px"> <apex:selectOptions value="{!selectedOptions}"/> </apex:selectList> </apex:panelGrid> </apex:pageBlock> <br/> <apex:commandButton value="Show Related Lists" action="{!show}"/> </apex:form> </apex:page>
After assembling the controller extension and these pages, navigate to
/apex/dynVFClassroom in your organization. You’ll see a
sequence similar to the following: