- Page |
- View source |
- History
An Introduction to Visualforce
Visualforce is the component-based user interface framework for the Force.com platform. The framework includes a tag-based markup language, similar to HTML. Each Visualforce tag corresponds to a coarse or fine-grained user interface component, such as a section of a page, or a field. Visualforce boasts about 100 built-in components, and a mechanism whereby developers can create their own components.
Visualforce uses the traditional model-view-controller (MVC) paradigm, with the option to use auto-generated controllers for database objects, providing simple and tight integration with the database. You can write your own controllers, or extensions to controllers, using Apex Code. Visualforce also provides AJAX components, and embeds the formula expression language for action, data and component binding interaction.
This article introduces Visualforce. It illustrates the major areas of functionality, provides an example of the MVC paradigm in action, shows how to include database integration, and demonstrates how to create your own components.
Visualforce in Action
A developer creates Visualforce pages by composing components, HTML, and optional styling elements on the Force.com platform. Just like HTML, Visualforce can integrate with any standard web technology or JavaScript framework to allow for a more animated and rich user interface. Each page is then accessible by a unique URL. When someone accesses a page, the server renders the page.
As the figure above illustrates, pages are constructed on the server and depending on the logic behind the page may interact with the database, invoke external web service calls, or both, before returning the view to the client (browser). In fact:
- Visualforce pages can react differently to different client browsers such as those on a mobile or touch screen device.
- Everything runs on the server, so no additional client-side callbacks are needed to render a complete view.
- Optional server-side call outs can be made to any Web service.
Let's see how this works in a little more detail.
Introducing Visualforce and the MVC Model
This section provides a quick overview of a simple Visualforce page, followed by some aspects of the MVC model. A simple example should give you a feel for Visualforce. Here's the code for a Visualforce page:
<apex:page standardController="Account">
<apex:form>
<apex:pageBlock title="Edit Account for {!$User.FirstName}">
<apex:pageMessages/>
<apex:pageBlockButtons>
<apex:commandButton value="Save" action="{!save}"/>
</apex:pageBlockButtons>
<apex:pageBlockSection>
<apex:inputField value="{!account.name}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
- The
pagecomponent wraps every Visualforce page, and itsstandardControllerattribute lets us make use of standard, automatically-generated, controller technology. - The
pageBlock,pageBlockButtonsandpageBlockSectiontags provide standard Salesforce styling for a section in a page, similar to what you see on a detail page. - The
inputFieldgenerates an appropriate input element, depending on the type of the field. - The
commandButtonrenders a button, which when pushed, invokes a standard method calledsave()on the controller.
When you visit the page with your browser, the platform renders it, producing something like the following:
There are some important aspects to this page:
- The
Accountstandard controller retrieved a record from the database considering the record Id found in the request (i.e., the URL), and made it available to the Visualforce page automatically. - The
$Uservariable provides access to details of the currently logged-in user. - The
{!account.name}expression retrieved the metadata associated with thenamefield of theAccountobject, rendered an appropriate input element, and initialized with the value from the Account retrieved from the database. - The label for the
namefield on Account is automatically displayed, and the input is highlighted as required by virtue of theinputFieldcomponent having been nested within apageBlockSection. - The
save()method on the controller provides a means of persisting the object back to the database. Had there not been a record in the request, this same action would attempt an insert of the account information provided in the form. - Any errors that occur in the submission of the form, either standard or custom, will be displayed by the
pageMessagescomponent.
The ease with which you can create powerful user interfaces that are tightly bound with the metadata, database, and controller layer is a key aspect of Visualforce. The following sections examine much of the functionality behind Visualforce.
The Model, View, Controller Paradigm
Visualforce pages are rendered on the server, and displayed on a client, typically a web browser. As such, they have server-side access to data and logic. Modern platforms will separate the database, model, and view out into separate layers. This gives you modularity, clear separation of concerns, and containment — ultimately making your application easier to code and maintain.
The following figure highlights the primary elements that comprise the capabilities of Visualforce as they pertain to the various layers of the MVC pattern illustrated in the following diagram.
In the figure:
- The model, or data structure, can be defined as either sObjects (the entity definitions for persisted data) or classes in Apex.
- The view, or presentation layer, is comprised of Pages and components as described above.
- The controller, or logic layer, includes any custom controller logic written in Apex, or standard behavior generated by the Force.com platform for each business entity.
The following figure shows the MVC layers in action with Visualforce:
Notice the following:
- The view, which is defined as our page defined above, containing the
apex:inputFieldcomponent. - The
apex:inputFieldcomponent is bound through the expression on its value attribute to the controller'sgetmethod on its account property. - The account property provides the view with the Account business entity object, the model in this example.
From the above diagram, the Account Name field presented in the page was rendered by inclusion of the apex:inputField Visualforce component. The value was derived through that component's value attribute expression, which calls into the controller layer for the get method on the controller's account property. Both the page and the controller are aware of the data structure and can interact with it directly — in this case the Account entity definition. As you can see, the expression uses simple dot notation to refer to the name field on the specific account instance.
For a full description of the database, and to Apex, the language used to code custom controllers, see An Introduction to the Force.com Database and An Introduction to Force.com Apex Code respectively. While the rest of this article may use both database and Apex functionality, it assumes you are familiar with these technologies.
Controllers and Extensions
Controllers and extensions provide the logic interaction and behavior for an application. Force.com provides standard controllers for all standard and custom business entities. These controllers provide access to standard platform behavior including saving, logic, and navigation. In the example above, the standard controller for account was specified so standard action methods such as save can be bound to action supporting components, such as apex:commandButton.
This is the signature for the save action method in the standard controller:
public PageReference save() {}
Clicking the button invokes the standard save process. Navigation is managed through the PageReference object that is returned from the method.
Custom controllers, written in Apex, deliver the flexibility to define your own logic, navigation, algorithms, and database and web services interactivity. With the stateful programming model provided by Visualforce, custom controllers can maintain state between pages making development of wizards straightforward. Custom controllers can themselves leverage the standard controller.
Assume that you have two database objects, Account and Contact. A simple controller class for a two step wizard that creates an Account and a related Contact might be defined as such:
public class MyWizardController {
public Account account { get; set; }
public Contact contact { get; set; }
public MyWizardController() {
account = new Account();
contact = new Contact();
}
public PageReference next() {
return Page.step2;
}
public PageReference previous() {
return Page.step1;
}
public PageReference save() {
Database.insert(account);
contact.accountId = account.id;
ApexPages.StandardController contactController = new ApexPages.StandardController(contact);
return contactController.save();
}
}
Note how Visualforce pages are first class citizens in the Apex language. In the above code, Page.step1 references a Visualforce page called step1, and if a button is bound to this action, the controller will redirect the user to the step1 page.
Finally, extensions provide the ability to augment standard or custom controllers. With extensions you can extend data access, adding logic or conditional navigation to an existing controller. An extension class is defined by providing a constructor which takes the controller type being extended as its argument. The following class definition extends the standard controller:
public class AccountExtension {
public Account account { get; set; }
public AccountExtension(ApexPages.StandardController controller) {
account = (Account) controller.getRecord();
}
}
Adding this controller to the page requires a simple change to the page component tag:
<apex:page standardController="Account" extensions="AccountExtension">
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:
<apex:page> </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:
<apex:page sidebar="false" showHeader="false"> </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:
<apex:page >
<apex:outputPanel layout="block" style="font-weight:bold">
Hello World!
</apex:outputPanel>
</apex:page>
And at the coarse end of the spectrum is apex:enhancedList. A simple reference like the following produces the respective output:
<apex:page>
<apex:enhancedList type="Contact" height="350"/>
</apex:page>
Let's change this page by adding one line after a simple <apex:pageBlock>:
<apex:page standardController="Contact">
<apex:pageBlock title="Simple Title">
<b>Hello <i>{!$User.FirstName}</i>.</b>
</apex:pageBlock>
<apex:detail subject="{!Contact.Id}" relatedList="false" />
</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 overlook apex: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:
<apex:page standardController="Account">
<apex:form>
<apex:pageBlock title="Edit Account for {!$User.FirstName}">
<apex:pageMessages/>
<apex:pageBlockButtons>
<apex:commandButton value="Save" action="{!save}"/>
</apex:pageBlockButtons>
<apex:pageBlockSection>
<apex:inputField value="{!account.name}"/>
<apex:inputField value="{!account.industry}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</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.
<apex:page standardController="Account">
<apex:form >
<apex:pageBlock id="in" title="Edit Account for {!$User.FirstName}">
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!quickSave}" rerender="out, in" status="status"/>
</apex:pageBlockButtons>
<apex:pageBlockSection >
<apex:inputField value="{!account.name}"/>
<apex:inputField value="{!account.industry}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
<apex:pageBlock id="out" title="Read View">
<apex:actionStatus startText="updating..." id="status"/>
<apex:pageBlockSection>
<apex:outputField value="{!account.name}"/>
<apex:outputField value="{!account.industry}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>
- The
rerenderattribute on thecommandButtonchanges the behavior from full to partial page, and specifies what areas of the page will be updated on the response — in this case, theapex:pageBlockcomponent tags with the named identifiers. - The status attribute on
commandButtonbinds the operation indication to the identifiedapex:actionStatuscomponent. - The
quickSave()method on the standard controller performs the same database operation as thesave()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:
<apex:page> <c:mycomponent> </apex:page>
With the definition of the component being simply:
<apex:component >
<fieldset>
<legend>MyComponent</legend>
<h1>Hello World!</h1>
</fieldset>
</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:
<apex:page >
<c:mycomponent text="Hello from the page!"/>
</apex:page>
With the added attribute component in the custom component definition:
<apex:component >
<apex:attribute name="text" type="String" description="My text to display"/>
<fieldset>
<legend>MyComponent</legend>
<h1>{!text}</h1>
</fieldset>
</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 styleClass attribute. For example this CSS:
<apex:page >
<apex:outputPanel style="border:2px solid red">
My Styled Panel
</apex:outputPanel>
</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:
<apex:page showHeader="false" standardStyleSheets="false">
<apex:outputPanel style="border:2px solid red">
My Styled Panel
</apex:outputPanel>
</apex:page>
You can also provide a stylesheet wherein you can maintain your own CSS class names:
<apex:page showHeader="false" standardStyleSheets="false">
<apex:styleSheet value="{!$Resource.styles}"/>
<apex:outputPanel styleClass="border_red">
My Styled Panel
</apex:outputPanel>
</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:
.mystyle {
background: url(img/mybackground.png);
font-size:18pt;
font-weight:bold;
width:220px;
height:59px;
}
Uploaded as a static resource named "styles", it can be referenced as such in a page:
<apex:page showHeader="true" standardStyleSheets="false">
<apex:styleSheet value="{!URLFOR($Resource.styles,'styles.css')}"/>
<apex:outputPanel styleClass="mystyle" layout="block">
My Styled Panel
</apex:outputPanel>
</apex:page>
Here:
- The static resource itself is named styles and is referenced through the
$Resourceglobal 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.pngis 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:
<apex:page renderAs="pdf" showHeader="false"> <h1>Hello PDF World!</h1> </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:
<messaging:emailTemplate subject="Contacts for {!relatedTo.Name}" recipientType="User" relatedToType="Account">
<messaging:plainTextEmailBody >
Account Name: {!relatedTo.name}
Contact Names:
<apex:repeat value="{!relatedTo.Contacts}" var="contact">
{!contact.name}
</apex:repeat>
</messaging:plainTextEmailBody>
<messaging:attachment renderAs="pdf" filename="contactlist">
<h1>{!relatedTo.Name}</h1>
<apex:dataTable value="{!relatedTo.Contacts}" var="contact">
<apex:column value="{!contact.name}"/>
<apex:column value="{!contact.phone}"/>
<apex:column value="{!contact.email}"/>
</apex:dataTable>
</messaging:attachment>
</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:plainTextEmailBodycomponent 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:mobileSample component:
<apex:page showHeader="false">
<c:mobileSample/>
</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.
<apex:component controller="mobileSampleCon">
<apex:image value="{!URLFOR($Resource.mobileImages, deviceType + '.jpg')}"/>
</apex:component>
public class mobileSampleCon {
public String deviceType { get; set; }
public MobileSampleCon() {
String userAgent = ApexPages.currentPage().getHeaders().get('USER-AGENT');
if(userAgent.contains('iPhone')) deviceType = 'iPhone';
else if(userAgent.contains('BlackBerry')) deviceType = 'BlackBerry';
}
}
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.
Force.com Sites
Force.com Sites is a technology that lets you create public websites and applications that run natively on the Force.com Platform. Force.com Sites harnesses Visualforce making it very easy to transform your current applications into public websites.
Force.com Sites is straightforward to use. A site is created by determining a domain name, and the defining a set of Visualforce pages that will be made available at that domain name. For example, you could create your own site "mysite.force.com", and expose a Visualforce page "helloWorld" as the default page. When any visitor then accesses the domain, they will see the output generated by the helloWorld Visualforce page.
Force.com Sites also include other functionality, such as caching and automatic feed generation — but Visualforce lies at its heart. To learn more about Force.com Sites please see An Introduction to Force.com Sites.
Summary
Visualforce is a powerful component-based user interface framework. While supporting the traditional model-view-controller design pattern, Visualforce also provides novel features that promote reuse (the component model), PDF generation, AJAX interactions, and mobile rendering. Visualforce is also well-integrated with the logic layer, Apex, which can be used to write custom controllers, and which also support Visualforce pages natively via the PageReference type.
Visualforce can be utilized to extend the value of existing applications by creating highly interactive and efficient user experiences with many ways of being integrated within the standard Force.com application architecture as well as a solid foundation for the creation of entirely new applications.
Visualforce is also used in other areas within the platform, such as in email templates and the Force.com Sites technology, which allows you to surface Visualforce pages to a public audience, effectively making it the primary technology for creating user interfaces for Web applications on the Force.com platform.
References
- Developer Force provides access to free developer edition accounts, which you can use to start developing immediately. It also provides links to documentation, forums, and more.
- The Visualforce topic page provides links to other Visualforce articles, videos, and code samples.
- See the Visualforce Developer's Guide for a comprehensive description of Visualforce.
- Developing Apps with jQuery contains a section, Integrating jQuery with Visualforce, that explains how to leverage jQuery within Visualforce pages.
- An Introduction to the Force.com Database provides an introduction to the query language and persistence mechanisms provided by the Force.com platform.
- An Introduction to Apex provides a comprehensive introduction to the Apex language, providing a lot more detail on all topics covered in this document.
- An Introduction to Force.com Sites provides an introduction to the enabling technology for exposing Visualforce in public web sites.