VISUALFORCE COMPONENTS


Standard Components

A Visualforce page can contain a mixture of HTML and Visualforce components. The HTML and component tags need to be well-formed, and all pages begin with the page component. For example, here is the most basic Visualforce page:
1<apex:page>
2</apex:page>
Each component has a set of optional and required attributes, which provide additional information to the component. For example, the following attributes remove the sidebar and top header in a Visualforce page:
1<apex:page sidebar="false" showHeader="false">
2</apex:page>
The Component Reference document , linked to from the Visualforce page edit/creation screens in the online builder, documents each component and its attributes. The following subsections provide a small taste of some of these standard components.

Output Components

There are varying degrees of granularity with standard output components. At the fine end of the spectrum is apex:outputPanel, which is a simple container that, in the case of HTML rendering, produces a div element:
1<apex:page >
2    <apex:outputPanel layout="block" style="font-weight:bold">
3        Hello World!
4    </apex:outputPanel>
5</apex:page>


And at the coarse end of the spectrum is apex:enhancedList. A simple reference like the following produces the respective output:
1<apex:page>
2    <apex:enhancedList type="Contact" height="350"/>
3</apex:page>


Let's change this page by adding one line after a simple <apex:pageBlock>:
1<apex:page standardController="Contact">
2   <apex:pageBlock title="Simple Title">
3      <b>Hello <i>{!$User.FirstName}</i>.</b>
4   </apex:pageBlock>
5    
6   <apex:detail subject="{!Contact.Id}" relatedList="false" />
7</apex:page>
In order for the above line of code to work, you need to have the Id of the contact in the URL. The standard controller does the work to supply this value dynamically into the merge field within the detail tag. Our page now looks like this :


As you can see, we now have the standard contact detail panel included! This looks and feels and behaves just like the standard contact detail panel, except of course it's embedded within our own page.
It's worth stressing this point: You can now construct your own Salesforce user interface pages that looks and feel just like the standard ones, enhanced in any way you like, reusing existing, standard Salesforce display components. Alternatively, you can make it look completely different, banishing all of the Salesforce look and feel.
Before we end this section, let's quickly learn more about the detail component. This component renders the detail page layout for a given object. Most components take optional attributes that refine the behavior in some way. Passing relatedList="false" to the<apex:detail> component ensures that it doesn't show any related lists beneath the details, as typically found when you view a contact.

Input Components

When creating forms, the most common input elements are covered by the generic types such as apex:inputCheckbox,apex:selectList, and apex:inputText. However, when working with the Force.com database entity definitions, do not overlookapex:inputField, as it delivers field type awareness, requiredness, editability, and formatting automatically based on the respective field definition.
For example, in the above code sample, the apex:inputField component was used to create the input element for the account's Name field. The addition of the standard Industry field on Account highlights type awareness:
01<apex:page standardController="Account">
02    <apex:form>
03        <apex:pageBlock title="Edit Account for {!$User.FirstName}">
04            <apex:pageMessages/>
05            <apex:pageBlockButtons>
06                <apex:commandButton value="Save" action="{!save}"/>
07            </apex:pageBlockButtons>
08            <apex:pageBlockSection>
09                <apex:inputField value="{!account.name}"/>
10                <apex:inputField value="{!account.industry}"/>
11            </apex:pageBlockSection>
12        </apex:pageBlock>
13    </apex:form>
14</apex:page>


Here, the two fields appear as you would expect based on their types:
  • The name field is a basic text input element based on its type and is marked as required automatically according to the field's definition.
  • The industry field is a picklist and all of its options are shown as defined on the field definition in setup.

AJAX Components

Enhancing the level of interactivity for a given interface can be accomplished using combination of standard components that will keep a user in context until their task is complete. Using the account edit form and by making a couple of small changes, we can demonstrate how this is done through the implementation of partial page updates.
01<apex:page standardController="Account">
02    <apex:form >
03        <apex:pageBlock id="in" title="Edit Account for {!$User.FirstName}">
04            <apex:pageMessages />
05            <apex:pageBlockButtons >
06                <apex:commandButton value="Save" action="{!quickSave}" rerender="out, in"status="status"/>    
07            </apex:pageBlockButtons>
08            <apex:pageBlockSection >
09                <apex:inputField value="{!account.name}"/>
10                <apex:inputField value="{!account.industry}"/>
11            </apex:pageBlockSection>
12        </apex:pageBlock>
13    </apex:form>
14    <apex:pageBlock id="out" title="Read View">              
15        <apex:actionStatus startText="updating..." id="status"/>
16        <apex:pageBlockSection>
17            <apex:outputField value="{!account.name}"/>
18            <apex:outputField value="{!account.industry}"/>
19        </apex:pageBlockSection>
20    </apex:pageBlock>
21</apex:page>
  • The rerender attribute on the commandButton changes the behavior from full to partial page, and specifies what areas of the page will be updated on the response — in this case, the apex:pageBlock component tags with the named identifiers.
  • The status attribute on commandButton binds the operation indication to the identified apex:actionStatus component.
  • The quickSave() method on the standard controller performs the same database operation as the save() method, but returns the user to the same page rather than navigating away.
The output of this page with an valid account Id in the request should look like this:


When the user changes a value and clicks on the "Save" button, the status will indicate the record is being updated:


When the update is complete, the component identified by the rerender attribute value "out" will be updated to reflect the changes to the model.

Custom Components

In addition to the standard components, Visualforce also includes the facility to create custom components. Custom Visualforce components are developed using a markup-based approach through composition of HTML or other Visualforce components (standard or custom). Custom components are referenced by name in a similar fashion to standard components with the difference being the namespace given to them.
A page that includes a custom component might simply look like this:
1<apex:page>
2   <c:mycomponent>
3</apex:page>
With the definition of the component being simply:
1<apex:component >
2    <fieldset>
3        <legend>MyComponent</legend>
4        <h1>Hello World!</h1>
5    </fieldset>
6</apex:component>
The output within the page would look like this:


Custom components also support strongly typed attributes. Allowing the consumer of the component to specify the text rather than always seeing "Hello World!" would require a simple attribute definition and passing of the desired value:
1<apex:page >
2    <c:mycomponent text="Hello from the page!"/>
3</apex:page>
With the added attribute component in the custom component definition:
1<apex:component >
2    <apex:attribute name="text" type="String" description="My text to display"/>
3    <fieldset>
4        <legend>MyComponent</legend>
5        <h1>{!text}</h1>
6    </fieldset>
7</apex:component>
The output within the page now looks like this:


Custom components can also have their own controllers, and attribute values can be passed into these controllers. Attributes support all primitives, Apex classes, and sObject definitions, including arrays of each.

Using Visualforce Pages

Visualforce pages can be incorporated into an application through multiple mechanisms. Here are a few ways to use Visualforce pages.

Display a Visualforce Page from a Tab

Here, the tab called "My Visualforce Page" is generated by a Visualforce page.

Display a Visualforce Page within a Standard Page Layout

In this scenario, Visualforce pages can be added to standard page layouts. To make Visualforce pages available in the page layout editor, set the standard controller of the Visualforce page you are trying to add inline to the page to that object. This standard controller can be both a standard or custom object; however, you can only have one object assigned to the standard controller at a time.

Display a Visualforce Page by Overriding Standard Buttons or Links

Instead of having standard buttons access standard functionality and pages, you can override them to instead invoke your custom Visualforce pages. Simply go to the Buttons and Links page for the object you want to override, and click Edit next to the appropriate button or link. If your standard controller is set properly, you should see the Visualforce page in the override picklist.

Display a Visualforce Page Using Custom Buttons or Links

Custom links and buttons can be added to standard page layouts, letting you call in to your Visualforce pages.

Display a Visualforce Page as the Target of a Link

As each Visualforce is addressable by a URL, so you can simply link to the pages.

Developing Visualforce Pages

There are multiple ways to edit Visualforce pages and its related types through the Web browser, APIs, and supported tools that use those APIs.

Browser-Based Development using Development Mode

A convenient way to edit pages online is through Development Mode. Development mode provides an in-place editing experience for your page and controller. Once you enable it on your user record under Setup | Personal Information | My Personal Information, you can create any page by entering a unique page URL and then selecting the quick fix.


Clicking on the quick fix to create the page navigates to the page, including the editor:


Pages and components can also be edited from their respective nodes under Setup:

Browser-Based Development using the Development Console

APIs

The primary Visualforce types are exposed in both the Metadata API as well as the standard Force.com SOAP API. The names of these types are:
  • ApexPage
  • ApexComponent
  • StaticResource
For more information, see the Documentation pages for these APIs.

Supported Tools

You can also use supported implementations of the Metadata API to help develop, migrate, and deploy Visualforce pages and applications containing these pages. For example:
  • Force.com Migration Tool — a library for the Apache Ant scripting/build tool that lets you deploy, migrate, and retrieve metadata, including Visualforce pages.
  • The Force.com IDE — an integrated development environment (IDE) for developing Force.com applications.
Here's a screenshot of the IDE in action:


Read An Introduction to the Force.com IDE for more information.

Look and Feel

Look and feel for pages can be managed using CSS by setting appropriate values for a given component's style or styleClassattribute. For example this CSS:
1<apex:page >
2  <apex:outputPanel style="border:2px solid red">
3      My Styled Panel
4  </apex:outputPanel>
5</apex:page>
produces this output:


One thing to note, inline styles are not ideal for efficient Visualforce pages. Using a style class, or reference to a style sheet, will render better performance overall in a custom page. Check out this session from Dreamforce on best practices for highly efficient Visualforce pages for more information.
In addition, if you'd like to take over the entire experience, you can remove the standard header, sidebar, and all stylesheets by setting the appropriate attributes on the page component tag:
1<apex:page showHeader="false" standardStyleSheets="false">
2  <apex:outputPanel style="border:2px solid red">
3      My Styled Panel
4  </apex:outputPanel>
5</apex:page>


You can also provide a stylesheet wherein you can maintain your own CSS class names:
1<apex:page showHeader="false" standardStyleSheets="false">
2  <apex:styleSheet value="{!$Resource.styles}"/>
3  <apex:outputPanel styleClass="border_red">
4      My Styled Panel
5  </apex:outputPanel>
6</apex:page>
The $Resource global refers to a static resource, described in the following section.

Static Resources

Traditional Web development often consists of various resources which are static in nature. These include CSS stylesheets, images, flash movies, JavaScript libraries, and more. Visualforce provides a convenient way to store and refer to these resources that takes advantage of browser caching to reduce the bandwidth footprint and improve performance of your pages. This was briefly introduced in the previous example for stylesheets.
In that example, the $Resource global is used to specify the static resource named styles, which, in this case, is a stylesheet that contains at least the 'border_red' class name. In addition to the various discrete types of resources, static resources also support structured archive file formats such as zip. Using a structured archive, it becomes possible to leverage many modern open JavaScript libraries and encapsulate your CSS styles that may include references to images.
For example, a style sheet defined as follows and named styles.css can be included in a structured archive along with the referenced image:
1.mystyle {
2   backgroundurl(img/mybackground.png);
3   font-size:18pt;
4   font-weight:bold;
5   width:220px;
6   height:59px;
7}
Uploaded as a static resource named "styles", it can be referenced as such in a page:
1<apex:page showHeader="true" standardStyleSheets="false">
2    <apex:styleSheet value="{!URLFOR($Resource.styles,'styles.css')}"/>
3    <apex:outputPanel styleClass="mystyle" layout="block">
4        My Styled Panel
5    </apex:outputPanel>
6</apex:page>
Here:
  • The static resource itself is named styles and is referenced through the $Resource global variable.
  • The URLFOR() function provides a mechanism to drill into the structure of the archive for the proper element — styles.css, in this case.
  • The relative reference in the stylesheet for img/mybackground.png is maintained through the blowout of the structure as the archive contains the folder named "img" at it's root and the respective file within it.
  • The resource and its referenced elements are cached by the browser at a versioned URL.
The panel now appears styled with the background image as follows:

PDF File Generation

The default rendering for Visualforce pages is HTML, but it is also possible to specify PDF as the rendering output for easily printing dynamic content. This rendering type is controlled through the renderAs attribute on page. The following simple page will be converted to PDF format on the server before being returned to the browser:
1<apex:page renderAs="pdf" showHeader="false">
2  <h1>Hello PDF World!</h1>
3</apex:page>
This attribute supports expressions for dynamic determination of the rendering format.

Email Templates

Email Templates also support Visualforce markup technology to create rich email messages.


Visualforce email templates are designated with the messaging:emailTemplate component tag. Additional email-specific components allow for specification of plain text and HTML bodies, as well as attachments. Attachments support the PDF rendering as well. The following is a basic example of how the same multi-level object data can be provided in an email to be sent to a user:
01<messaging:emailTemplate subject="Contacts for {!relatedTo.Name}" recipientType="User"relatedToType="Account">
02   <messaging:plainTextEmailBody >
03       Account Name: {!relatedTo.name}
04       Contact Names:
05       <apex:repeat value="{!relatedTo.Contacts}" var="contact">
06           {!contact.name}
07       </apex:repeat>
08   </messaging:plainTextEmailBody>
09   <messaging:attachment renderAs="pdf" filename="contactlist">
10       <h1>{!relatedTo.Name}</h1>
11       <apex:dataTable value="{!relatedTo.Contacts}" var="contact">
12           <apex:column value="{!contact.name}"/>
13           <apex:column value="{!contact.phone}"/>           
14           <apex:column value="{!contact.email}"/>           
15       </apex:dataTable>
16   </messaging:attachment>
17</messaging:emailTemplate>


Note the following:
  • The standard controller behind this email template provides access to the recipient User and the related Account exactly like a Visualforce page would.
  • The text body of the email is as specified within the messaging:plainTextEmailBody component tags.
  • The attachment component contains markup that will be attached as HTML or as PDF similar to the page mechanism.

Mobile Pages

Visualforce tabs, as described above, can also be flagged as "mobile ready", which makes them available for any mobile configuration.


Once added to a user's mobile configuration settings, a capable mobile device with the salesforce.com mobile client will include this tab. When selected, it launches a live browser connection to show the Visualforce page underlying the tab. For example, the following simple page renders the appropriate platform image depending upon the device type detected within the c:mobileSamplecomponent:
1<apex:page showHeader="false">
2   <c:mobileSample/>
3</apex:page>
The markup for the c:mobileSample component simply displays an image stored within a static resource named mobileImages, but determines which image to display at runtime based on the browser's reported user agent value as inspected in the component's controller.
01<apex:component controller="mobileSampleCon">
02   <apex:image value="{!URLFOR($Resource.mobileImages, deviceType + '.jpg')}"/>
03</apex:component>
04 
05public class mobileSampleCon {
06 
07   public String deviceType { get; set; }
08 
09   public MobileSampleCon() {
10       String userAgent = ApexPages.currentPage().getHeaders().get('USER-AGENT');
11        
12       if(userAgent.contains('iPhone')) deviceType = 'iPhone';
13       else if(userAgent.contains('BlackBerry')) deviceType = 'BlackBerry';
14   }
15}
There is also an open source library up on GitHub containing Visualforce mobile components to simplify the development of Visualforce mobile apps. The framework contains lightweight Visualforce UI components that generate cross-platform HTML5 output that runs well on smartphones and tablets.
Finally, as of Winter '13 Salesforce Touch has gone GA. For the first iteration of Touch, you can see the data that is accessible from the Sales App including sales data and custom object data. It is built with HTML5 technology meaning that the app is device agnostic and accessible from any device with any modern browser.


2 comments:

  1. Very Impressive Salesforce tutorial. The content seems to be pretty exhaustive and excellent and will definitely help in learning Salesforce course. I'm also a learner taken up Salesforce training and I think your content has cleared some concepts of mine. While browsing for Salesforce tutorials on YouTube i found this fantastic video on Salesforce. Do check it out if you are interested to know more.https://www.youtube.com/watch?v=2hR0H2nxA4I

    ReplyDelete