Visualforce is a web development framework that enables developers to build sophisticated, custom user interfaces for mobile and desktop apps that can be hosted on the Force.com platform. You can use Visualforce to build apps with user interfaces that look like the standard interface provided by Force.com, as well as your own completely custom interface.
Visualforce enables developers to extend Salesforce’s built-in features, replace them with new functionality, and build completely new apps. Use powerful built-in standard controller features, or write your own custom business logic in Apex. You can build functionality for your own organization, or create apps for sale in the AppExchange.
Visualforce app development is familiar to anyone who has built web apps. Developers create Visualforce pages by composing components, HTML, and optional styling elements. Visualforce can integrate with any standard web technology or JavaScript framework to allow for a more animated and rich user interface. Each page is accessible by a unique URL. When someone accesses a page the server performs any data processing required by the page, renders the page into HTML, and returns the results to the browser for display.
Where You Can Use Visualforce
Display a Visualforce Page from a Tab
Display a Visualforce Page in Salesforce1 Display a Visualforce Page within a Standard Page Layout Display a Visualforce Page by Overriding Standard Buttons or Links
Display a Visualforce Page Using Custom Buttons or Links
Link Directly to a Visualforce Page
Display a Visualforce Page in Salesforce1 Display a Visualforce Page within a Standard Page Layout Display a Visualforce Page by Overriding Standard Buttons or Links
Display a Visualforce Page Using Custom Buttons or Links
Link Directly to a Visualforce Page
Introduction to Global Variables and Visualforce Expressions
Global Variables
Use global variables to access and display system values and resources in your Visualforce markup.
For example, Visualforce provides information about the logged-in user in a global variable called $User. You can access fields of the $User global variable (and any others) using an expression of the following form: {! $GlobalName.fieldName }.
There are nearly two dozen global variables that can be used within Visualforce. They’re useful for getting information about the currently logged in user, as you saw, but also for getting details about the organization ($Organization), settings ($Setup), details about custom objects ($ObjectType), actions available on those objects ($Action), and so on.
- {! $User.FirstName}
- {!$USER.FIRSTNAME}
- {! $user.firstname }
Formula Expressions
Visualforce lets you use more than just global variables in the expression language. It also supports formulas that let you manipulate values.
For example, the & character is the formula language operator that concatenates strings.
<p>Tomorrow will be day number {! DAY(TODAY() + 1) }</p>
<p>Let's find a maximum: {! MAX(1,2,3,4,5,6,5,4,3,2,1) } </p>
<p>The square root of 49 is {! SQRT(49) }</p>
<p>Is it true? {! CONTAINS('salesforce.com', 'force.com') }</p>
Conditional Expressions
Use a conditional expression to display different information based on the value of the expression.<p>{! IF( CONTAINS('salesforce.com','force.com'),
'Yep', 'Nope') }</p>
<p>{! IF( DAY(TODAY()) < 15,
'Before the 15th', 'The 15th or after') }</p>
({! IF($User.isActive, $User.Username, 'inactive') })
<apex:detail />
<apex:detail relatedList="false"/>
<apex:relatedList list="Contacts"/>
<apex:relatedList list="Opportunities" pageSize="5"/>
<apex:pageBlock title="Contacts">
<apex:pageBlockTable value="{!Account.contacts}" var="contact">
<apex:column value="{!contact.Name}"/>
<apex:column value="{!contact.Title}"/>
<apex:column value="{!contact.Phone}"/>
</apex:pageBlockTable>
</apex:pageBlock>
Coarse-grained components let you quickly add lots of functionality to a page, while fine-grained components give you more control over the specific details of a page.<apex:enhancedList> and <apex:listViews> are other coarse-grained components that you might want to use with or in place of <apex:relatedList>. And there are many other components that pack a lot of functionality into a single tag. If you haven’t done it yet, check out the Standard Component Reference and see what the range of possibilities are.<apex:pageBlockTable> is an iteration component that picks up the platform styling. <apex:dataTable> and<apex:dataList> are iteration components for creating tables and lists without the platform styling. And <apex:repeat> is an iteration component that you can use to generate any arbitrary markup for a collection of records.You may have noticed that your manually created related lists are missing some things that were added to the table created by<apex:relatedList>. For example, the Edit and Del links to edit and delete individual records is missing, and so is the New Contact button. To create these user interface elements you need to know a little more Visualforce, specifically about forms and actions. You’ll learn about that elsewhere.
<apex:form>
<apex:inputField>
<apex:commandButton>
<apex:page standardController="Account">
<apex:form>
<apex:pageBlock title="Edit Account">
<apex:pageBlockSection>
<apex:inputField value="{! Account.Name }"/>
</apex:pageBlockSection>
<apex:pageBlockButtons>
<apex:commandButton action="{! save }" value="Save" />
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>
The <apex:inputField> component renders the appropriate input widget based on a standard or custom object field’s type. For example, if you use an <apex:inputField> tag to display a date field, a calendar widget displays on the form. If you use an<apex:inputField> tag to display a picklist field, as we did here for the industry field, a drop-down list displays instead.
<apex:inputField> can be used to capture user input for any standard or custom object field, and respects any metadata that is set on the field definition, such as whether the field is required or unique, or whether the current user has permission to view or edit it.
<apex:pageMessages/>
<apex:pageBlock title="Contacts">
<apex:pageBlockTable value="{!Account.contacts}" var="contact">
<apex:column>
<apex:outputLink
value="{! URLFOR($Action.Contact.Edit, contact.Id) }">
Edit
</apex:outputLink>
<apex:outputLink
value="{! URLFOR($Action.Contact.Delete, contact.Id) }">
Del
</apex:outputLink>
</apex:column>
<apex:column value="{!contact.Name}"/>
<apex:column value="{!contact.Title}"/>
<apex:column value="{!contact.Phone}"/>
</apex:pageBlockTable>
</apex:pageBlock>
There’s obviously a great deal more to learn about building useful, usable forms for your web apps.
For starters, Visualforce offers a dozen or so input components, not just <apex:inputField>. <apex:inputField> works well with the standard controller and for directly editing record data. For pages where you’re using your own custom controller code, or when form input doesn’t map directly to fields on a record, you’ll want to know about some of the others. Most of these components have names that begin with “apex:input”, and you can find them grouped together in the component reference. For select lists and radio button controls, look for the components with names that start with “apex:select” instead.
For user interfaces intended to be used on mobile devices, you’ll want to check out <apex:input>, which is designed to be used in HTML5 pages, and allows you to use a variety of features that make the resulting input user elements mobile friendly.
The code you wrote here made use of a number of actions provided by the standard controller for the page. We call thesestandard actions, and there are quite a few of them. There’s a core set that are available for all objects with standard controllers, but many of the built-in standard objects have additional actions you can use.
Speaking of actions, you were able to add actions to edit and delete existing related contacts. How can you add the ability to create new related contacts? It’s not quite as easy as creating a link using the create action, the way you did with edit anddelete. This is because those actions worked on existing records, which already have a relationship to the associated account. But when you create a new record, you need to create that relationship yourself. That will require you to write some custom controller code of your own.
Introduction to the Standard List Controller
The standard list controller allows you to create Visualforce pages that can display or act on a set of records.
Displaying a list of records is a fundamental behavior of almost all web apps. Visualforce makes it extremely easy to display a list of records of the same type, using just markup, no back-end code. The secret, as usual, is the standard controller, in this case, the standard list controller.
The standard list controller provides many powerful, automatic behaviors such as querying for records of a specific object and making the records available in a collection variable, as well as filtering of and pagination through the results. Adding the standard list controller to a page is very similar to adding the standard (record) controller, but with the intent of working with many records at once, instead of one record at a time.
Display a List of Records
Use the standard list controller and an iteration component, such as <apex:pageBlockTable>, to display a list of records.
The standard (record) controller makes it easy to get a single record loaded into a variable you can use on a Visualforce page. The standard list controller is similar, except instead of a single record, it loads a list, or collection, of records into the variable.
Add List View Filtering to the List
Use {! listViewOptions } to get a list of list view filters available for an object. Use {! filterId } to set the list view filter to use for a standard list controller’s results.
The standard list controller provides a number of features you can use to alter the display of the list. One of the most powerful is list view filters. You create list view filters declaratively, using clicks instead of code, and the standard list controller lets you use any defined list view filter on the page.
<apex:page standardController="Contact" recordSetVar="contacts">
<apex:form>
<apex:pageBlock title="Contacts List" id="contacts_list">
Filter:
<apex:selectList value="{! filterId }" size="1">
<apex:selectOptions value="{! listViewOptions }"/>
<apex:actionSupport event="onchange" reRender="contacts_list"/>
</apex:selectList>
<!-- Contacts List -->
<apex:pageBlockTable value="{! contacts }" var="ct">
<apex:column value="{! ct.FirstName }"/>
<apex:column value="{! ct.LastName }"/>
<apex:column value="{! ct.Email }"/>
<apex:column value="{! ct.Account.Name }"/>
</apex:pageBlockTable>
</apex:pageBlock>
<!-- Pagination -->
<table style="width: 100%">
<tr>
<td>
Page: <apex:outputText value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>
</td>
<td align="center">
<!-- Previous page -->
<!-- active -->
<apex:commandLink action="{! Previous }" value="« Previous" rendered="{! HasPrevious }"/>
<!-- inactive (no earlier pages) -->
<apex:outputText style="color: #ccc;" value="« Previous" rendered="{! NOT(HasPrevious) }"/>
<!-- Next page -->
<!-- active -->
<apex:commandLink action="{! Next }" value="Next »" rendered="{! HasNext }"/>
<!-- inactive (no more pages) -->
<apex:outputText style="color: #ccc;" value="Next »" rendered="{! NOT(HasNext) }"/>
</td>
<td align="right">
<!-- Records per page -->
Records per page:
<apex:selectList value="{! PageSize }" size="1">
<apex:selectOption itemValue="5" itemLabel="5"/>
<apex:selectOption itemValue="20" itemLabel="20"/>
<apex:actionSupport event="onchange" reRender="contacts_list"/>
</apex:selectList>
</td>
</tr>
</table>
</apex:form>
</apex:page>
The standard list controller provides many features that are common in web apps, many more than have been covered here.
For example, in addition to the Previous and Next actions, which move backwards and forwards one page at a time, there are also First and Last actions that go to the beginning or end of the list of records.
Behind the scene of your markup, the standard list controller is based on the StandardSetController Apex class. You can read more about it, and all the features it provides, in the Force.com Apex Code Developer's Guide.
There’s a small elephant in the room with the examples we created here, and its name is sorting. It’s often desirable to have a default sort order for a list, and also to have sort-affecting column headers that let you change the sort order on the fly. The simple truth is, you can’t affect the sort order using Visualforce alone. Although the amount of additional Visualforce markup andApex code required to support sorting and clickable column headers isn’t enormous, it does require custom code. See the additional resources for some starting points.
Introduction to Static Resources
Static resources allow you to upload content that you can reference in a Visualforce page. Resources can be archives (such as .zip and .jar files), images, stylesheets, JavaScript, and other files.
Static resources are managed and distributed by Force.com, which acts as a content distribution network (CDN) for the files. Caching and distribution are handled automatically.
Static resources are referenced using the $Resource global variable, which can be used directly by Visualforce, or used as a parameter to functions such as URLFOR().
<apex:page>
<!-- Add the static resource to page's <head> -->
<apex:includeScript value="{! $Resource.jQuery }"/>
<!-- A short bit of jQuery to test it's there -->
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).ready(function() {
jQuery("#message").html("Hello from jQuery!");
});
</script>
<!-- Where the jQuery message will appear -->
<h1 id="message"></h1>
</apex:page>
<apex:page showHeader="false" sidebar="false" standardStylesheets="false">
<!-- Add static resources to page's <head> -->
<apex:stylesheet value="{!
URLFOR($Resource.jQueryMobile, 'jquery.mobile-1.4.4.css') }"/>
<apex:includeScript value="{! $Resource.jQuery }"/>
<apex:includeScript value="{!
URLFOR($Resource.jQueryMobile, 'jquery.mobile-1.4.4.js') }"/>
<div style="margin-left: auto; margin-right: auto; width: 50%">
<!-- Display images directly referenced in a static resource -->
<h3>Images</h3>
<p>A hidden message:
<apex:image alt="eye" title="eye"
url="{!URLFOR($Resource.jQueryMobile, 'images/icons-png/eye-black.png')}"/>
<apex:image alt="heart" title="heart"
url="{!URLFOR($Resource.jQueryMobile, 'images/icons-png/heart-black.png')}"/>
<apex:image alt="cloud" title="cloud"
url="{!URLFOR($Resource.jQueryMobile, 'images/icons-png/cloud-black.png')}"/>
</p>
<!-- Display images referenced by CSS styles,
all from a static resource. -->
<h3>Background Images on Buttons</h3>
<button class="ui-btn ui-shadow ui-corner-all
ui-btn-icon-left ui-icon-action">action</button>
<button class="ui-btn ui-shadow ui-corner-all
ui-btn-icon-left ui-icon-star">star</button>
</div>
</apex:page>
Introduction to Custom Controllers
Custom controllers contain custom logic and data manipulation that can be used by a Visualforce page. For example, a custom controller can retrieve a list of items to be displayed, make a callout to an external web service, validate and insert data, and more—and all of these operations will be available to the Visualforce page that uses it as a controller.
<apex:page controller="ContactsListController">
<apex:form>
<apex:pageBlock title="Contacts List" id="contacts_list">
<!-- Contacts List -->
<apex:pageBlockTable value="{! contacts }" var="ct">
<apex:column value="{! ct.FirstName }">
<apex:facet name="header"> <!-- Makes it Clickable -->
<apex:commandLink action="{! sortByFirstName }"
reRender="contacts_list">First Name
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.LastName }">
<apex:facet name="header">
<apex:commandLink action="{! sortByLastName }"
reRender="contacts_list">Last Name
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{! ct.Title }"/>
<apex:column value="{! ct.Email }"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
public class ContactsListController {
private String sortOrder = 'LastName';
public List<Contact> getContacts() {
List<Contact> results = Database.query(
'SELECT Id, FirstName, LastName, Title, Email ' +
'FROM Contact ' +
'ORDER BY ' + sortOrder + ' ASC ' +
'LIMIT 10'
);
return results;
}
public void sortByLastName() {
this.sortOrder = 'LastName';
}
public void sortByFirstName() {
this.sortOrder = 'FirstName';
}
}
The header text for the first name and last name columns is hard-coded in this markup. But what if your users don’t all use English? The standard Salesforce user interface has translated versions of the field names for all standard objects, and you can provide your own translations for custom objects. How would you access these? Instead of the plain text, try this markup: <apex:outputText value="{! $ObjectType.Contact.Fields.FirstName.Label }"/>. That’s the right way to reference a field’s label, even if your organization all uses the same language, because it will automatically update if the field name is ever changed.
Custom controllers and the Apex language let you do pretty much anything you can think of in your Visualforce pages.
Getter methods pull data out of your controller onto your page. There are corresponding setter methods that let you submit values from the page back up to your controller. Like getter methods, you prefix your setters with “set”, and other than that, they’re just methods that take an argument.
An alternative to getters and setters is to use Apex properties. Properties are kind of a combination of a variable with getter and setter methods, with a syntax that groups them together more clearly. A simple property that references a custom object might be declared like this.
1 | public MyObject__c myVariable { get; set; } |
Properties can be public or private, and can be read-only, or even write-only, by omitting the get or set. And you can create implementations for the get or set methods, when you want to perform additional logic besides simply saving and retrieving a value.
Properties are a general feature of Apex, not specific to Visualforce. Apex is a complete programming language, and in addition to being the natural partner for building complex Visualforce pages, it’s used in many other Force.com development contexts. See the Apex topics elsewhere here, and the resources at the end of this page for many ways to learn to use Apex fully.
The lifecycle of a Visualforce request and response can seem complex initially. In particular, it’s important to understand that there’s no specific order in which getters or setters (or properties, if you use them) are called, so you must not introduce order-of-execution dependencies between them. There’s a lot more detail available to you in the relevant sections of the VisualforceDeveloper’s Guide, in particular the “Custom Controllers and Controller Extensions” chapter.
Comments
Post a Comment