Sunday, 21 October 2012

Dynamic Visualforce Components


Visualforce is primarily intended to be a static, markup-driven language that lets developers create a user interface that matches the Salesforce look-and-feel. However, there are occasions when it is necessary to programmatically create a page. Usually, this is to achieve complicated user interface behavior that is difficult or impossible with standard markup.
Dynamic Visualforce components offer a way to create Visualforce pages that vary the content or arrangement of the component tree according to a variety of states, such as a user’s permissions or actions, user or organization preferences, the data being displayed, and so on. Rather than using standard markup, dynamic Visualforce components are designed in Apex.
A dynamic Visualforce component is defined in Apex like this:
Component.Component_namespace.Component_name
For example, <apex:dataTable> becomes Component.Apex.DataTable.
The Standard Component Reference contains the dynamic representation for all valid Visualforce components.
Visualforce components that are dynamically represented in Apex behave like regular classes. Every attribute that exists on a standard Visualforce component is available as a property in the corresponding Apex representation with get and set methods. For example, you could manipulate the value attribute on an <apex:outputText> component as follows:
Component.Apex.OutputText outText = new Component.Apex.OutputText();
outText.value = 'Some dynamic output text.';
Consider using dynamic Visualforce components in the following scenarios:
  • You can use dynamic Visualforce components inside complex control logic to assemble components in combinations that would be challenging or impossible to create using equivalent standard Visualforce. For example, with standardVisualforce components, you typically control the visibility of components using the rendered attribute with the global IF() formula function. By writing your control logic in Apex, you can choose to display components dynamically with a more natural mechanism.
  • If you know that you’ll be iterating over objects with certain fields, but not specifically which objects, dynamic Visualforce components can “plug in” the object representation by using a generic sObject reference. 
Note:
====
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.

This tag acts as a placeholder for your dynamic Apex components. It has one required parameter—componentValue—which accepts the name of an Apex method that returns a dynamic component.
The following Visualforce components do not have dynamic Apex representations:
<apex:attribute>
<apex:component>
<apex:componentBody>
<apex:composition>
<apex:define>
<apex:dynamicComponent>
<apex:include>
<apex:insert>
<apex:param>
<apex:variable>
===========
Example
========
<apex:page controller="SimpleDynamicController">
    <apex:dynamicComponent componentValue="{!dynamicDetail}" /> 
</apex:page>

/* Controller */ 
    
public class SimpleDynamicController {

    public Component.Apex.Detail getDynamicDetail() {
        Component.Apex.Detail detail = new Component.Apex.Detail();
        detail.expressions.subject = '{!acct.OwnerId}';
        detail.relatedList = false;
        detail.title = false;
        return detail;
    }

    // Just return the first Account, for example purposes only 
    
    public Account acct {
        get { return [SELECT Id, Name, OwnerId FROM Account LIMIT 1]; }
    }
}

=================If you want to another example click on this link  Account Search page

Displaying Visualforce Components from Apex Class using DynamicComponent


Here i am trying to explain to display the visualforce components from apex class by using DynamicComponent Tag.

On every component we have

Dynamic Visualforce Notation in component reference for example


for <apex:inputField> we have Dynamic Visualforce Notation is Component.Apex.InputField
By using this type of notations i build search page for searching Account records by account name.
By using this we can control the visualforce components from Apex Class.

Controller:
=============
public with sharing class DynamicComponentExample11 {
    public DynamicComponentExample11(ApexPages.StandardController con) { }
    public string enterstring{get;set;}
    public List<Account> lstaccount{get;set;}
    public Component.Apex.SectionHeader getHeaderWithDueDateCheck() {
        date dueDate = date.newInstance(2011, 7, 4);
        boolean overdue = date.today().daysBetween(dueDate) < 0;

        Component.Apex.SectionHeader sectionHeader = new Component.Apex.SectionHeader();
        if (overdue) {
            sectionHeader.title = 'This Form Was Due On ' + dueDate.format() + '!';
            return sectionHeader;
        } else {
            sectionHeader.title = 'Form Submission';
            return sectionHeader;
        }
    }
 
    Public List<Account> getAccounts(){
     
        if(enterstring!=null && enterstring!='')
            lstaccount=[select id,name,type,industry from account where name like:enterstring+'%'];
        else
            lstaccount=[select id,name,type,industry from account];
        return lstaccount;
 
    }
    public void search1(){
        getAccounts();
     
    }


 public Component.Apex.PageBlock getpageBlock(){
        Component.Apex.PageBlock pb=new Component.Apex.PageBlock();
        Component.Apex.PageBlockTable  ptable=new Component.Apex.PageBlockTable();
        Component.Apex.OutputLabel optlabel=new Component.Apex.OutputLabel();
        Component.Apex.CommandButton cmdbtn=new Component.Apex.CommandButton();
        cmdbtn.value='Search';
        cmdbtn.expressions.action='{!search1}';
        optlabel.value='Enter Name';
        Component.Apex.Inputtext intext=new Component.Apex.InputText();
        intext.id='searchtext';
        intext.expressions.value='{!enterstring}';
        optlabel.for='intext';
        ptable.expressions.value='{!accounts}';
        ptable.var='a';
        if(enterstring!=null && enterstring!='')
         ptable.rendered=true;
        else
         ptable.rendered=false;
        Component.Apex.Column namecolumn=new Component.Apex.Column();
        namecolumn.expressions.value='{!a.name}';  
        Component.Apex.Column industrycolumn=new Component.Apex.Column();
        industrycolumn.expressions.value='{!a.Industry}';
        Component.Apex.Column typecolumn=new Component.Apex.Column();
        typecolumn.expressions.value='{!a.type}';
        pb.childcomponents.add(optlabel);
        pb.childcomponents.add(intext);
        pb.childcomponents.add(cmdbtn);
        pb.childcomponents.add(ptable);
        ptable.childcomponents.add(namecolumn);
        ptable.childcomponents.add(typecolumn);
        ptable.childcomponents.add(industrycolumn);
        return pb;
    }
}
=====================
Visualforce page
============================

<apex:page standardcontroller="Account" extensions="DynamicComponentExample11">
    <apex:form >
           <apex:dynamicComponent componentValue="{!pageBlock}"/>
    </apex:form>
</apex:page>

=======================
Output:
======