Force.com Tutorial: An Introduction to Visualforce
Abstract
Visualforce is the new force.com technology that lets you create custom user interfaces for your Force.com applications. With Visualforce, you can reuse many of the components found in existing Salesforce interfaces, or create your own. Moreover, the interfaces can also tap into custom business logic. The technique is powerful, easily customized, separates business logic from user interface design, and in most cases eliminates the need for S-Controls. The custom pages can either complement and extend existing pages on Salesforce, or have their own unique look and feel.
The trinity of the existing Force.com platform together with Visualforce and their associated controllers provide a way to construct traditional MVC web applications, albeit hosted on the Force.com platform.
After briefly looking at S-Controls and introducing a basic Visualforce example, this article provides a series of tutorials that contain enough material for you to get started building your own applications utilizing Visualforce.
- Tutorial: Getting Started shows how to configure Visualforce and get started with the mini development environment.
- Tutorial: Standard Controllers provides a more in-depth look at Visualforce and shows how to trigger a Visualforce Page from a standard Contact page.
- Tutorial: Custom Controllers looks at how to incorporate custom business logic and produce AJAX-style effects on a page.
- Tutorial: Web Applications In A Jiffy shows how to create a completely custom web application using the Force.com platform.
Note: Visualforce comes standard with your Developer Edition org. If you do not have a DE org, please signup to get it for free.
From S-Controls to Visualforce
Before diving into the four tutorials, let's quickly revisit S-Controls. We'll then give you a quick look at what can be accomplished with Visualforce.
Of course, S-Controls are now disparaged so you can't develop any new ones. But you can edit existing ones, and install S-Controls that exist in legacy managed packages.
The Traditional Approach: S-Controls
Let's look at the traditional approach to customizing Salesforce applications using S-Controls. HTML S-Controls let you create custom content that is typically hosted by the system but executed by client applications. These S-Controls will usually have a mix of HTML and JavaScript. The JavaScript would make use of the Salesforce AJAX Toolkit to retrieve and update Salesforce data, while the HTML would control the display of these data. Here's a simple example that displays the name of the current user:
<html>
<head>
<script type="text/javascript" src="/js/functions.js"></script>
<script src="/soap/ajax/8.0/connection.js"></script>
<script>
function setupPage() {
var user = sforce.connection.getUserInfo().userFullName;
document.getElementById('userNameArea').innerHTML = 'Hello '+user;
}
</script>
</head>
<body onload=setupPage()>
<div id=userNameArea>
</div>
</body>
</html>
The sforce JavaScript object can also be used to perform more complex Apex queries, but the general procedure is the same: Have your HTML call a number of JavaScript routines that perform the queries and manipulate the data for display. Once you've created an S-Control, you can then embed them in your Salesforce application by including them on a page layout, or using them to generate the output in a tab for example.
While S-Controls are powerful beasts, they do suffer from a few setbacks:
- They typically mix user interface design and code. Ideally you'd like your coders writing the business logic and your user interface design team working on the layout, independently and concurrently.
- Controlling the look and feel is difficult. Indeed, you'll have to employ Salesforce CSS and the Stylesheets and S-Controls Best Practice Guide, if you want your output to look and feel like the standard Salesforce application.
- You can't make use of existing layout components. For example, if you want to create a new tab with your data, which also displays the standard Contact details page, you'd have to recreate the standard Contact details page with your custom code.
Visualforce eliminates these setbacks. They separate user interface from code, they are composed on the Salesforce servers and not on the client, they provide an easy way to control look and feel, and they support reuse of existing logic. They're also really easy to use and provide a powerful way of hooking in your own business logic.
The New Kid On The Block: Visualforce Pages
Each Visualforce consists of a page containing custom markup language and HTML, and an optional controller. You will typically find the user interface in the page itself, and business logic in customer controllers associated with the page. As a taster, here is a simple Visualforce page that we created. We called it MySamplePage and it just contains the following text:
<apex:page standardController="Contact">
<apex:pageBlock title="Simple Title">
<b>Hello <i>{!$User.FirstName}</i>.</b>
</apex:pageBlock>
</apex:page>
This results in the following output:
There are some interesting things about this page:
- It uses a mixture of HTML (see the
<b>and<i>tags) and the Visualforce markup language. In fact, you can use any HTML you like here, so you can rapidly construct attractive page additions. However, you do not want to use DreamWeaver, FrontPage, or other WYSIWIG HTML code generator toos: stick with Eclipse. The Visualforce markup language (we'll just call it "markup" going forward) is always contained in theapexnamespace. That is, the tags always begin:<apex:someTag> - The page looks and feels like any other page associated with Contacts. Note the colors, fonts and spacing follow the usual style for Contacts.
- The Contacts tab is also highlighted because Salesforce can determine that this page is associated with Contacts.
- All Visualforce Pages follow a simple URL pattern:
http://yourSalesForceHost.salesforce.com/apex/PageName - Just like S-Controls, Visualforce Pages support embedded merge fields, like the
{!$User.FirstName}used in the example.
You've just been introduced to your first two Visualforce Page components:
page- this component is used as a top-level container component for all Visualforce Pages.pageBlock- this renders a standard, titled container that takes its style from the current page context
Let's change this page in a fundamental way by simply adding one line after the <apex:pageBlock> tag:
<apex:detail relatedList="false" />
Our page now looks like this (we've not shown how we selected the particular contact here):
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: 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 Salesorce look and feel.
Before we end this section, here's a look at this new component:
detail- this renders the detail page layout for a given object. Most components take optional attributes that refine the behavior in some way. PassingrelatedList="false"to the<apex:detail>component ensures that it doesn't show any related lists beneath the details, as usually found when you view a contact.
Now that you have a feel for what Visualforce can do, let's dive into a few tutorials. The first, Getting Started, gets you up and running with your first Visualforce Page. The next, Standard Controllers, shows how to create an enhanced Contact details page utilizing the standard business logic that comes with Contact objects. The Custom Controllers tutorial shows how to build in your own custom logic and modify the look and feel. The example also makes use of AJAX. The final tutorial, Web Applications In A Jiffy, looks at how to use the new technology to create your own web applications.
Tutorial: Getting Started
Here are 3 quick steps to getting you started using Visualforce. As you'll be developing Visualforce Pages, the first thing you'll want to do is enable Visualforce Developer Mode.
Step 1: Sign-up and configure
Sign up for a Developer Edition org, then click through to Setup -> My Personal Information -> Personal Information -> Edit. Enable the Development Mode checkbox and then hit Save.
This provides you with some wiki-like functionality:
- If you browse to any Visualforce Page that doesn't exist, you will be offered the option of creating it.
- When viewing a Visualforce Page, a footer appears that offers you the option of editing the Visualforce Page or its associated controller (if it exists):
" - If you expand the
Page EditororController, you'll be able to edit the page or code in an editor embedded within that page, right there in your browser:
The editor also has a handy reference to the component library documentation. - * Note this doesn't work for Google Chrome browser
Now you're ready to create your first page.
Step 2: Create your first page
If you're logged in to your account at Salesforce.com, your URL will currently look something like:
https://<salesforceHost>.salesforce.com/...
Simply enter a new address in your browser's address bar, which follows this form:
https://<salesforceHost>.salesforce.com/apex/PageName
For example, I'm on the Salesforce host called na3, so to create a new page called HelloWorld, I simply have to navigate to this address:
https://na3.salesforce.com/apex/HelloWorld
You'll then be presented with an option to create the page.
For the more traditional approach to creating a new page, navigate to the new Setup -> Develop -> Pages and select New Visualforce Page.
Step 3: Add content and view
You can now simply start writing your markup for the page. If you're using the built-in editor, every time you hit Save, you'll see the change reflected in the top panel. If you're not, visit the page to see the change.
It's pretty easy to get started. Let's now have some fun by creating a few interesting Visualforce Pages.
Tutorial: Standard Controllers
Visualforce pages come in two flavors, set by the attributes on the <apex:page> markup tag. Pages that have the standardController attribute will start something like this:
<apex:page standardController="SomeObjectType">
Controllers provide data and business logic that a Visualforce page can make use of. Standard Controllers are automatically made available with every object in your Salesforce application. Visualforce pages associated with standard controllers cannot have custom business logic associated with them, but they are associated with the type of object specified in the attribute in a very strong way. This tutorial shows how to get started with Visualforce Pages using Standard Controllers. We'll create a simple page that shows Contact Details, and then show how to override the standard Contact List to use the new Contact Details page. We then will work on an exercise to enhance the page by creating a tiny mashup.
Step 1: Create a new Visualforce Page for Contacts
Think of standard controllers as specifying a context in which data on the page will be retrieved and displayed. The components and merge fields on the pages then provide a way of interacting with the controller. Let's make this more concrete. Create a Visualforce Page (see the first tutorial) called MyContactDetails with the following markup:
<apex:page standardController="Contact">
<apex:pageBlock title="My Contact Details">
<p>Hello {!contact.FirstName}</p>
</apex:pageBlock>
<apex:detail relatedList="false" />
</apex:page>
You can read this markup as instruction to display a page block, followed by a details panel, for Contact objects using the look and feel usually associated with Contact objects.
Step 2: Accessing the page (a useful cheat)
The question now remains, how to set the context object? One quick test approach is to list your current contacts by hitting the Contacts tab. If you examine the link to a contact you'll see something like this:
https://na3.salesforce.com/0035000000N1Gwj
This gives us the ID of the contact, 0035000000N1Gwj, so you can now go ahead and call your new Visualforce page like so:
https://na3.salesforce.com/apex/MyContactDetails?id=0035000000N1Gwj
The page you created will now display the first name and details of this particular Contact information.
Step 3: Accessing the Page (a better way)
Let's look at a better approach to calling our page. If you hit the Contacts tab in your Salesforce application, you'll see the default list of contacts:
What you are going to do now is override what happens when you select a contact from this list. To do this, click through to Setup -> Customize -> Contacts -> Buttons and Links:
From this configuration screen you can override the actions that occur when standard buttons and links are selected. In this case, override the View label.
Ensure Visualforce is selected, and select the new MyContactDetails Visualforce Page. Note that Salesforce will automatically provide viable candidates in this option list; in this case, all Visualforce pages that have Contact as their standard controller.
If you now go back to the Contacts tab and select a contact, you'll see Salesforce changes to the same URL as before, except this time your own details page is used to display the details of the contact.
In other words, you now have a way of transparently extending existing Salesforce user interface pages. This is a powerful feature, which as you can see is dead simple to set up.
Exercise: Building a simple mashup
At this point, you've managed to override the default Contact display page with something that looks, feels and behaves just like the standard Contact display page. You can extend it in any way you like, mixing and matching other standard components, adding your own functionality, linking to other sites, embedding mashups, and so on. Here's a little example.
A simple approach to creating a mashup is to make use of the merge fields of the object being displayed. For example you have access to the contact's address Contact.MailingAddress, so if you wanted to customize the contact display page with a map, simply add another <apex:pageBlock> with the appropriate JavaScript/HTML from your favorite mapping tool, making sure to embed {!Contact.MailingAddress} and so on in the appropriate fields.
What makes this little mashup so nice is that it fits in so seamlessly with the existing look and feel. The article Mashups: The What and Why motivates why building mashups is a good thing, and Tutorial: Creating Flex Salesforce Mashups shows how to create a Flex-based mashup.
Tutorial: Custom Controllers
So far our Visualforce Pages have made use of the fields and functionality of the controller automatically associated with each object due to our use of the standardController attribute in the <apex:page> tag. Now we are going to build a Visualforce Page that has access to our own business logic.
In this tutorial we're going to build a custom Tab that lists Salesforce contacts. When you click on a contact, it will direct Salesforce to fetch data associated with the contact using an Apex query, and update a details panel. This update will be made without a page refresh, using AJAX. Here's our goal:
The idea is that if you click on, say, Tim Barr, then the "Fetched Data" is refreshed with data fetched from a query.
This will appear to be quite a complex little setup, but, as we'll see, it's a cinch to create with Visualforce.
Step 1: Create a Visualforce Page that uses a custom controller
Create a new Visualforce page, say PageMashup, with the following markup:
<apex:page controller="MyController" > <apex:pageBlock title="Contacts"> </apex:pageBlock> </apex:page>
The first thing you'll note when you save this page is that the system will make a Controller option available in the editor. If you click through, you'll see the default controller that is created:
public class MyController {
}
This is a simple Apex class, and the home to all your custom business logic.
Step 2: Fetch the contacts
Let's enhance our controller class with some logic to fetch the 10 most recently modified contacts. Just add the following method:
public List<Contact> getMyContacts() {
return [SELECT Id, Name, Account.Name FROM Contact
ORDER BY LastModifiedDate DESC LIMIT 10];
}
It's a standard Apex method, with no reference to anything Visualforce specific. If you refresh the PageMashup page, you'll see no change. In fact, the getMyContacts() won't even execute. We'll need to modify the Visualforce page to display the result of invoking this method. You do this by treating the method like a merge field. In this, since our method is called getMyContacts(), a merge field called myContacts is made available. So simply adding the following to the page will do the job:
{!myContacts}
Here's the result:
It's not pretty, but you can clearly see that the page is now making a call into our controller.
Step 3: Improve the display
You'll notice the green border in the previous panel. When using the standard controllers, Salesforce "knew" which look and feel to use because you assigned it an object type. With custom controllers, this information is no longer available. To make up for it, add an attribute tabStyle="Contact" to the <apex:page> component. Now it'll have the standard Contact colors, and the Contact tab will highlight when you access the page.
Now let's do something about that list of identifiers being displayed for the contacts. Visualforce Pages has components that can iterate over collections that can be used here; we'll be using the dataTable component:
dataTable- Renders an HTML Table by iterating over the items in the set value. The table contains one or more column tabs that define the columns of the table. Each column is rendered as a single "td" element.
Let's look at the code in our revised page:
<apex:page controller="MyController" tabStyle="Contact">
<apex:pageBlock title="Contacts">
<apex:dataTable value="{!myContacts}" var="aContact" width="100%" >
<apex:column>
<apex:facet name="header"><b>Name</b></apex:facet>
{!aContact.Name}
</apex:column>
<apex:column >
<apex:facet name="header"><b>Account Name</b></apex:facet>
{!aContact.Account.Name}
</apex:column>
</apex:dataTable>
</apex:pageBlock>
</apex:page>
You'll see that the value attribute of dataTable takes {!myContacts} as a parameter. In other words, when this renders it will make a call into our custom controller and fetch the contacts by calling the getMyContacts() method. The dataTable tag then iterates over the collection of contacts that is returned, assigning the variable aContact to each contact as it loops around.
The innards of our dataTable takes each contact and displays the associated Name and Account.Name, each in their own columns. It's pretty intuitive stuff, and the iterators are a great boon. This is what the result looks like:
As this step shows, Visualforce lets you quite clearly differentiate the user interface design from the coding of the business logic. Let's now go one step further, and add some AJAX functionality.
Step 3: Add AJAX updates
Visualforce has built-in support for AJAX. The documentation refers to this functionality with the rerender attribute. The idea is that if you have an identified component, say an output panel, then certain commands can be told to "re-render" that component. In this case, Visualforce Pages simply refreshes the output panel, not the entire page. The idea is simple, and the implementation is equally simple.
A thing to note is that the AJAX functionality works with HTML "forms". To get the AJAX functionality to work here, we'll need an <apex:form> tag around the contents of the page. The form component has additional components (such as inputField) which we won't be showing here, but which can be used to build any input form you like.
Next, let's create the panel where we want our AJAX-rendered text to appear.
<apex:pageBlock title="Fetched Data">
<apex:outputPanel id="resultPanel" layout="block">
Result: {!fetchedData}"
</apex:outputPanel>
</apex:pageBlock>
Here's the description of the new tag:
outputPanel- Use for components grouping in the AJAX output area, which offers several additional output opportunities.
One way to think of outputPanel is as a named placeholder for text that can be dynamically changed.
You'll have noticed the merge field, {!fetchedData}, in the output panel. We'll need an accompanying method in our controller. Our eventual goal is to allow someone to click on a name, and for that to result in the panel being rerendered, using data fetched from our service. So for now we're going to supply a simple implementation:
String result='Click on an account to fetch the data';
public String getFetchedData() {
return result;
}
Eventually we'll write some logic to modify the result variable's value.
To complete our AJAX adventure, we need to add links that invoke an action. We'll change the way in which our first column is rendered, to read as follows:
<apex:column>
<apex:facet name="header"><b>Name</b></apex:facet>
<apex:commandLink action="{!invokeService}"
value="{!aContact.name}" rerender="resultPanel">
<apex:param name="id" value="{!aContact.id}"/>
</apex:commandLink>
</apex:column>
The commandLink tag places a hyperlink around the contact's name, which when clicked, calls the invokeService() method in our controller (which we'll have to create). The magic lies in the rerender="resultPanel" attribute. Note that it must have the same value is the identifier we assigned to the outputPanel. The hyperlink it generates can also pass through parameters; in this case we're passing the identifier of the contact. Here's the documentation for each of these tags:
commandLink- Renders an HTML hyperlink. An AJAX form submit is generated on a click. The component allows dynamic re-rendering after a response comes back.param- Sets a parameter for the component associated with the enclosing tag. Tags that support this component areoutputLink, outputText, actionFunction, actionSupport, commandLink, or commandButton.
All that we need to do now is write the invokeService() method. Here's a simple implementation:
public PageReference invokeService() {
Id id = System.currentPageReference().getParameters().get('id');
result = [SELECT Name FROM Contact WHERE Id=:id].Name;
//returning null indicates the same page should be returned - in place change
return null;
}
This code grabs the identifier from the incoming parameter (the global System object provides this access) and then performs an Apex query for the contact's name. It stores this in the result variable and returns null. Because null is returned, no page change takes place, however note the following: the name is stored in the result variable, which the outputPanel displays. We'll come across the PageReference type again in the next tutorial.
That's it. When someone clicks on a name, the invokeService() method is called, which updates the result variable. Because of the rerender attribute on the commandLink, after the action is carried out the resultPanel will be refreshed (in-place, using AJAX), which will then display the new value. Painless AJAX, custom logic and customizable look and feel.
For your reference, here is the complete page at this point
<apex:page controller="MyController" tabStyle="Contact">
<apex:form>
<apex:pageBlock title="Contacts">
<apex:dataTable value="{!myContacts}" var="aContact" width="100%">
<apex:column>
<apex:facet name="header"><b>Name</b></apex:facet>
<apex:commandLink action="{!invokeService}"
value="{!aContact.name}"
rerender="resultPanel">
<apex:param name="id" value="{!aContact.id}"/>
</apex:commandLink>
</apex:column>
<apex:column>
<apex:facet name="header"><b>Account Name</b></apex:facet>
{!aContact.Account.Name}
</apex:column>
</apex:dataTable>
</apex:pageBlock>
<apex:pageBlock title="Fetched Data">
<apex:outputPanel id="resultPanel" layout="block">
Result: {!fetchedData}
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>
Tutorial: Web Applications In A Jiffy
The Model-view-controller (MVC) approach to engineer software is now the de facto standard. It decouples data access (the model) from presentation (the view) and user interaction, by introducing a controller to mediate between the two. If you've built web applications using Java EE, .NET, PHP or Rails, you'll be familiar with this approach.
The introduction of Visualforce Pages lets you embrace this paradigm on the Force.com platform too. This short tutorial provides a taste of how to create a small web application in two minutes. It requires a little more knowledge of the basic Force.com platform.
Step 1: Create the Model
Salesforce is built around persisting models of your business data. You can use the built-in Salesforce objects like Account and Contact, or you can create your own. These objects can have a rich set of field types, as well as relationships with other objects. The Apex Query Language lets you navigate these relationships and retrieve the data that you want. In this short example, we're going to create our own object for handling blog posts.
Navigate to Setup -> Build -> Custom Objects -> New Custom Object. Set the Label and Object Name to BlogPost, and the plural label to BlogPosts. Save the object, and then hit New under Custom Fields & Relationships. Create a field with type Text Area (Long), setting its name to Content and #Visible Lines to 5.
You now have a custom object that Salesforce can persist, update, delete and so on. All of these operations come free, out of the box. You also have standard fields for Created By and Last Modified By, a facility to create validation rules, and the standard Salesforce security as well. This is a rich persistence engine, now configured to handle our model.
Step 2: Create an Entry Screen
We want two view pages: one to list all blog posts, and another to create blog posts. Let's create the entry screen first, which will allow us to write a blog post. We'll do this with a Visualforce Page called blogedit. Create the page by navigating to:
https://<salesforceHost>>.salesforce.com/apex/blogedit
Here's the complete code for the page:
<apex:page standardcontroller="BlogPost__c" showHeader='false'>
<apex:form>
<p><b>Title</b><br />
<apex:inputField value="{!BlogPost__c.Name}"/>
</p>
<p><b>Post Content</b><br />
<apex:inputField value="{!BlogPost__c.Content__c}" />
</p>
<apex:commandButton value="Save" action="{!Save}"/>
</apex:form><br />
<apex:form>
<a href="/apex/blog">Back to listing</a>
</apex:form>
</apex:page>
Note the standard use of __c to denote custom fields and objects. This looks pretty much like any other Visualforce Page that we've created thus far. It's a simple form that utilizes the standard controller. This allows us to use the action Save. We've added the showHeader="false" attribute to remove completely the default Salesforce look and feel. Here's the result:
While it may not look pretty (something easily fixed with a style sheet), it has all the necessary components and it is functional. You can add a title and content, and hit save and a new record will be persisted. It also has a few pleasant surprises. For example, the inputField tag has created an input area 5 lines deep, as indicated when we created the field. There's another great surprise lurking here too, which we'll see in a minute.
Step 3: Creating a listing for our blogs
As a final step, we want to create a page that lists all our blogs. As you probably guessed after reading the code in Step 2, create the following page:
https://<salesforceHost>>.salesforce.com/apex/blog
We want to list the blog posts, as well as provide a button to create a new post. Our code looks like this:
<apex:page controller="blogController" showHeader="false">
<apex:form>
<apex:repeat value="{!Posts}" var="post">
<h2 id="title"><a href="/apex/blogedit?id={!post.id}">{!post.name}</a></h2>
<p><i>{!post.content__c}</i></p>
<p>Posted by
{!post.CreatedBy.Name} on {!post.CreatedDate}
</p><hr />
</apex:repeat>
</apex:form>
<apex:form>
<apex:commandButton value="NewPost" action="{!newPost}"/>
</apex:form>
</apex:page>
Let's walk through it. It's a page that uses a custom controller, blogController, and which has two forms. The first form will show all the posts, while the second form has a button to create a new post. To show all the posts, we iterate through the posts ({!Posts}) displaying the title, content and Created By and Created Date fields. Finally, note that we link the titles to the blogedit Visualforce page that we created in Step 2, passing in the identifier.
The controller obviously has two pieces to it. It needs a getPosts() method so that this page can call {!Posts}, and it needs a method to handle {!newPost}. Here's the code for getPosts():
public BlogPost__c[] getPosts() {
return [select Name, id, CreatedDate, CreatedBy.Name,
Content__c from BlogPost__c];
}
This simply returns an array of BlogPosts by performing an Apex query.
The code for newPost() is a little tricker, making use of the PageReference type:
public PageReference newPost() {
PageReference pr = Page.blogedit;
pr.setredirect(true);
return pr;
}
All this does is redirect to the blogedit page. Being able to reference pages like this and then redirect to them is very powerful. You can, for example, use this to build a multistep wizard because these controllers can maintain state across page interactions.
That's it! Here's the result:
With a little CSS applied, you'll get something a little more recognizable as a blog:
There's a little extra magic lurking here. If you click on the title of a blog post, it will take you to the blogedit page as indicated in the code. However, since we've supplied the Id of the record, Salesforce treats this as an edit, not as a new object creation. So blogedit with its standard controller is really doing object creation and edit for free.
Setting up a simple web application like this is usually quite involved. Visualforce on the Force.com platform has made it rather painless. We get a great persistence engine, query language, validation, security and web service interface for free. In addition, Visualforce lets you completely customize the presentation of the web application.
Summary
Visualforce fundamentally changes the way in which developers approach the Force.com platform. They provide a clear separation between business logic, and look and feel. The ability to override standard screens coupled with the page components that let you reuse standard display and business logic, lets you create custom Visualforce pages that seamlessly extend the Force.com platform. The ease with which you can further extend these pages with mashups, AJAX and web service integration demonstrates their versatility and extensibility.
Finally, the Visualforce Pages platform provides you with an MVC platform that you can use to build your own custom application. Visualforce provides you with the view and controller components, while the standard Force.com platform provides comprehensive model management with custom objects, validations, relationships and query language.
The tutorials in this article, together with the references below, will get you started building these application on the Force.com platform. Good luck!
References
Author -Jon Mountjoy





