Build Killer Visualforce Pages with Dynamic Visualforce Components

I love Dynamic Visualforce Components!

About a year ago, I had a requirement to build a Visualforce Page that had repeating tabs in it. I figured I would just just throw a <apex:repeat> in my page and be done. Not so fast. You’d think it would be easy but it was actually impossible at the time. My code started out like this:

<apex:tabPanel>
   <apex:tab label="Tab 1"/>
   <apex:tab label="Tab 2"/>
   <apex:tab label="Tab 3"/>
</apex:tabPanel>
Standard Visualforce Tabs

BUT, I needed the tabs to be dynamic.

I needed the information on the Visualforce Page to be loaded using code in an Apex Controller. Here’s what I tried:

<apex:tabPanel>

    <apex:repeat value="{!tabLabels}" var="t">
      <apex:tab label="{!t}"></apex:tab>
   </apex:repeat>

</apex:tabPanel>

Should work right? Nope! Nothing like learning on the fly!  And I learned that you can’t put a tab inside a “repeater”. I ended up solving this issue with some jQuery but something easy turned into something a bit difficult. At the time, I was anticipating the release of Dynamic Visualforce Components. It was announced but then pulled from the General Availability of the Summer ’11 release.

Thankfully, Dynamic Visualforce Components are now available.  I hated the wait but I love them now that they’re here and I’m learning new ways to use them with every project. Here’s how I solved the example above:

The Visualforce Code becomes just one line:

<apex:dynamicComponent componentValue="{!myTabs}"/>

Here’s the Apex to create a tabPanel dynamically:

public Component.Apex.TabPanel getMyTabs()
{
//create parent panelComponent.Apex.TabPanel myTabPanel = new Component.Apex.TabPanel();
for (integer i=0;i<3;i++)  //just a sample, this could easily be a SOQL loop
{
Component.Apex.Tab myTab = new Component.Apex.Tab();
 myTab.Label = 'Tab ' + string.valueOf(i+1);
  //add child tabs to the parent
    myTabPanel.childComponents.add(myTab);
}
return myTabPanel;
}

The code above makes the following dynamic tabPanel:

Dynamic Visualforce TabPanel

Dynamic Visualforce TabPanel


“We want a radio group on a Visualforce page. The values for the radioGroup items on should come from the available picklist items of a custom field and depending upon certain parameters, some of the radio group items should be disabled.”
Dynamic Visualforce Components are very awesome and very powerful! Adding dynamic “stuff” to a Visualforce using an Apex Controller is right up my alley: I’m a backend developer and definitely not a frontend web guy. I recently had a new requirement that I was only able to solve with Dynamic Visualforce Components. I was really excited to put Salesforce’s new functionality to work for me. Here’s the requirement:

Sounds simple! But this could never be accomplished using standard Visualforce. Dynamic Visualforce Components to the rescue! Here’s what I did (in a nutshell): Again my Visualforce Code is still just one line (loving it!):

<apex:dynamicComponent componentValue="{!dynamicRadioGroup}"/>

Here’s the Apex to create a dynamic radio group:

public Component.Apex.form getDynamicRadioGroup() {

 //I put the form component in here. You may not want to do this
   Component.Apex.form form = new Component.Apex.form();

   Component.Apex.outputLabel label = new Component.Apex.outputLabel();
      label.value = 'My Dynamic Radio Group';
  Component.Apex.selectRadio radioGroup = new Component.Apex.selectRadio();
      radioGroup.id = 'selectRadio';
      radioGroup.layout='pageDirection';
   for (integer i=0;i<5;i++) 
   {
      Component.Apex.selectOption so = new Component.Apex.selectOption();
         so.itemValue = string.valueOf(i+1);
         so.itemLabel = 'Item # ' + string.valueOf(i+1);
         so.itemDisabled = math.mod(i,2)==0; //freaky cool!
      radioGroup.childComponents.add(so); 
   }
   Component.Apex.selectOption so = new Component.Apex.selectOption();
      so.itemValue = 'Random';
      so.itemLabel = 'Random';
      so.itemDisabled = false;
   form.childComponents.add(Label);

   form.childComponents.add(radioGroup);

   radioGroup.childComponents.add(so);
   return form;

}

You can see in the example above how I created an entire form and added other components (i.e. outputLabel) to the page just using Apex. For the sample code, I’m disabling the even numbered items.  Here’s what it looks like:

Dynamic Visualforce RadioGroup

Dynamic Visualforce RadioGroup

 

 

 

 

 

Salesforce’s reference guide says this about Dynamic Visualforce Components “Dynamic Visualforce is a powerful feature for advanced developers, and you’ll want to read about it in depth before using it.”

Then the reference guide goes further to say this: “Dynamic Visualforce components are not intended to be the primary way to create new Visualforce pages in your organization. Existing Visualforce pages shouldn’t be rewritten in a dynamic manner and, for most use cases, standard Visualforce components are acceptable and preferred. You should only use dynamic Visualforce components when the page must adapt itself to user state or actions in ways that can’t be elegantly coded into static markup.”

I understand what they’re saying BUT don’t we want to build pages that adapt themselves and are dynamic? Maybe 100% of Visualforce Pages don’t need to be dynamic but you’ll do well to put it into your bag of tricks!