Friday 7 September 2012

Add an Action Method to a Controller - Visualforce


In this lesson you add an action method, a method that is invoked when the user of your Visualforce page clicks on a button or link. You previously used such a method,save(), on the standard controller—now you’ll write your own. The goal is to modify the page to dynamically display a selected account record’s list of contacts.
  1. Click MyController to edit the controller for your Visualforce page.
  2. Below the line public class MyController { add the following two lines:
    public Id selectedAccount { get; set; }  
    public List<Contact> contactsInformation { get; set; }
    This creates two properties. The first, selectedAccount, is an identifier, while the second, contactsInformation, is a list of Contact records.
  3. Click AccountWithContacts to edit the Visualforce page, and add the following snippet just below the </apex:form> line:
    <apex:outputPanel id="ContactDetail">
        <apex:repeat value="{! contactsInformation}" var="contact">
            <p>{! contact.FirstName & ' ' & contact.LastName}</p>
        </apex:repeat>
    </apex:outputPanel>
    This iterates over the list of contacts (remember, contactsInformation is defined to return List<Contact>), displaying their first and last names.
    At this point, you can save the page and you’ll notice no change. What you need to do now is ensure that when an account name is clicked, thecontactsInformation property is populated with that account record’s contacts.
  4. Modify your controller by clicking MyController and adding the following before the final brace:
    public void accountClicked() {
        contactsInformation = [SELECT FirstName, LastName FROM Contact 
                WHERE AccountID = :selectedAccount];
    }
  5. Replace the line <apex:outputTextvalue="{! acct.name}"/> in your Visualforce page with the following:
    <apex:commandlink action="{! accountClicked}" rerender="ContactDetail"> <apex:outputText value="{! acct.name}"/>
        <apex:param name="id" value="{! acct.Id}" assignTo="{!selectedAccount}"/>
    </apex:commandLink>
    This uses the rerender attribute to ensure that the output panel is refreshed using an Ajax update.
  6. Click Save.
    Now when you select an account record with related contacts, the contacts for that record are dynamically displayed below the list of accounts.
A lot happens when you click the name of an account:
  • Because an <apex:param> component is supplied, the ID of the current account is first assigned to the property selectedAccount in the controller. So now the controller knows which account you selected.
  • Because the account name is wrapped in an <apex:commandLink> component, the method indicated in the action attribute, accountClicked(), is invoked.
  • When the accountClicked() method runs, it performs a simple query, using the selectedAccount identifier, and assigns the result to thecontactsInformation property.
  • Because the <apex:commandLink> component has a rerender attribute, the output panel dynamically renders, which in turn iterates over thecontactsInformation and displays the contacts’ names.
That’s a lot to digest! Take your time, experimenting by removing attributes, modifying the methods, and noting what changes occur. Also, refer back to Tutorial #11: UpdatingVisualforce Pages with Ajax to learn more about the Ajax effect.

Add a Method to Retrieve Account Records - Visualforce


You’re now ready to write getMyAccounts(), which simply returns the list of 10 accounts most recently modified.
  1. Click the MyController tab.
  2. Modify the getMyAccounts() method to read as follows:
    public List<Account> getMyAccounts() {
        return [SELECT Id, Name, AccountNumber FROM Account ORDER BY
               LastModifiedDate DESC LIMIT 10];
    }
  3. Click Save.
Your page now displays the names of the 10 most recently modified accounts. The Visualforce expression {! myaccounts} causes Visualforce to execute yourgetMyAccounts() method in the MyController class. That method returns a list of account records, which is what the <apex:dataList> component iterates over.

Create a Page with a Controller - Visualforce


You create controllers the same way you created extensions in the previous tutorial, by navigating to Setup | Develop | Apex Classes | New. You can also have the Visualforceeditor create them for you.
  1. Create a new Visualforce page named AccountWithContacts.
  2. Enter the following as the body of the page:
    <apex:page controller="MyController">
        <apex:form>
            <apex:dataList value="{! myaccounts}" var="acct">
                <apex:outputText value="{! acct.name}"/>
            </apex:dataList>
        </apex:form>
    </apex:page>
    The contents of the page will be very familiar to you. The primary component iterates over a list of accounts, displaying their names. Where is myaccounts defined? It’s not defined yet, but it will reside in the controller that you specified, MyController.
  3. Click Save.
  4. Visualforce notes that the class MyController doesn’t exist. Click Create Apex class 'public class MyController'.
  5. Visualforce notes that there’s an unknown property myaccounts and offers to create it for you. Click Create Apex method 'MyController.getMyAccounts'.
You will notice two things in your Visualforce editor. First, there’s another error message: Unknown property 'String.name'. This happens because you haven’t quite fully defined the getMyAccounts() method yet. Visualforce doesn’t know the type that will be returned by that method. You’ll also notice a new tab has appeared next to Page Editor titled Controller. This lets you modify the controller’s Apex class.

Visualforce development mode Page Editor

Creating and Using Custom Controllers - Visualforce

Tutorial #4: Using Standard Controllers introduced how Visualforce supports the Model-View-Controller (MVC) style of user interface creation. Controllers typically retrieve the data to be displayed in a Visualforce page, and contain code that executes in response to page actions, such as a command button being clicked. Up until this point, you’ve been using a standard controller—a set of logic provided for you out of the box by the platform. In this tutorial you create your own controller by writing Apex code.


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.


Add an Extension to a Visualforce Page


Tutorial #8: Inputting Data with Forms shows how to create a very simple form. In this lesson you will duplicate that page, adding the extension functionality:
  1. Create a new Visualforce page called MyAccountWithExtension.
  2. Use the following as the body of the page:
    <apex:page standardController="Account" extensions="MyExtension"> 
        <p>{!title}</p>
        <apex:form>
            <apex:inputField value="{!account.name}"/>
            <apex:commandButton action="{!save}" value="Save!"/>
        </apex:form>
    </apex:page>
  3. Now access your page with a valid Account identifier passed in as a parameter. Your URL will look something like:https://na6.visual.force.com/apex/MyAccountWithExtension?id=0018000000MDfn1
What you’ll find is that your form pre-populates the input field with the name of the identified account. Great! And it also shows your fancy title with the account name and identifier.
Sample Extension to Rename an Account
When you save the page, you’ll notice that a new line appears above the form. Here’s what’s happening in your page:
  • The attribute extensions="MyExtension" ensures that Visualforce instantiates a copy of your Apex class MyExtension, passing in a reference to the current controller (you’re using the standard controller for Account).
  • The syntax {! title} instructs Visualforce to look for a method called getTitle() and insert the result of calling that method. Because there is such a method in your extension, Visualforce executes it and replaces the statement with the result.

Create a Controller Extension - Visualforce


Controller extensions are Apex classes. Creating your first Apex class is as easy as creating your first Visualforce page.
  1. Click Setup | Develop | Apex Classes.
  2. Click New.
  3. Enter the following as the body of the Apex class:
    public class MyExtension {
        private final Account acct;
        
        public MyExtension(ApexPages.StandardController controller) {
            this.acct = (Account)controller.getRecord();
        }
        public String getTitle() {
            return 'Account: ' + acct.name + ' (' + acct.id + ')';
        }
    }
This is an Apex class named MyExtension that has an instance variable named acct. It has a constructor that retrieves the record from the controller parameter, and saves it in the acct variable. The class also has a method called getTitle() that returns a string containing the account’s name and identifier.
Most extensions have this form—with the constructor being the key ingredient. When the extension is used, Visualforce automatically invokes the constructor, passing in the controller for the page being viewed. This controller provides access to the record being viewed.

Using Extensions to Add Functionality - Visualforce

You have already used standard controllers, which provide a set of functionality such as automatic record retrieval, saving, and updating. Sometimes you will want more—perhaps you want to perform additional processing or record retrieval. You can do this by adding a controller extension, which is a custom Apex class that contains functionality that can be accessed from your Visualforce page.


Controller extensions are Apex classes that extend the functionality of a controller. They allow you to add methods that can be called from your Visualforce pages. A Visualforcepage can have more than one extension, and the same extension can be used in multiple Visualforce pages—providing another use case for extensions: as containers for additional functionality for sharing across a number of controllers.

Learning More

  • The Apex Language Reference Guide documents the methods available in the StandardController class. This lesson uses getRecord(). Also available arecancel()delete()edit()getId()save(), and view().
  • For an introduction to the Apex programming language, read the Apex Workbook.

Add Dynamic Re-Rendering - Visualforce

Now you need to add elements to the page that set the page parameter and dynamically render the region you’ve named detail:
  1. Modify your page by adding a new page block beneath your current one:
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataList value="{! account.Contacts}" var="contact">
                {! contact.Name}
            </apex:dataList>
        </apex:form>
    </apex:pageBlock>
    This iterates over the list of contacts associated with the account, creating a list that has the name of each contact.
  2. Click Save.
    If you access your page, you’ll see the list of contacts. Now you need to make each contact name clickable.
  3. Modify the {! contact.Name} expression by wrapping it in an <apex:commandLink> component:
    <apex:commandLink rerender="contactDetails"> {! contact.Name} <apex:param name="cid" value="{! contact.id}"/> </apex:commandLink>
There are two important things about this component. First, it uses a rerender="contactDetails" attribute to reference the output panel you created earlier. This tellsVisualforce to do a partial page update of that region when the name of the contact is clicked. Second, it uses the <apex:param> component to pass a parameter, in this case the id of the contact.
If you click any of the contacts, the page dynamically updates that contact, displaying its details, without refreshing the entire page.


Visualforce provides native support for Ajax partial page updates. The key is to identify a region, and then use the rerender attribute to ensure that the region is dynamically updated.

Learning More

There’s a lot more to the Ajax and JavaScript support:
  • <apex:actionStatus> lets you display the status of an Ajax request—displaying different values depending on whether it’s in-progress or completed.
  • <apex:actionSupport> lets you specify the user behavior that triggers an Ajax action for a component. Instead of waiting for an <apex:commandLink> component to be clicked, for example, the Ajax action can be triggered by a simple mouse rollover of a label.
  • <apex:actionPoller> specifies a timer that sends an Ajax update request to Force.com according to a time interval that you specify.
  • <apex:actionFunction> provides support for invoking controller action methods directly from JavaScript code using an Ajax request.
  • <apex:actionRegion> demarcates the components processed by Force.com when generating an Ajax request.

Identify a Region for Dynamic Updates - Visualforce


A common technique when using Ajax in Visualforce is to group and identify the region to be dynamically updated. The <apex:outputPanel> component is often used for this, together with an id attribute for identifying the region.
  1. Create a Visualforce page called Dynamic, using the following body:
    <apex:page standardController="Account">
        <apex:pageBlock title="{!account.name}">
            <apex:outputPanel id="contactDetails">
                <apex:detail subject="{!$CurrentPage.parameters.cid}"
                    relatedList="false" title="false"/>
            </apex:outputPanel> </apex:pageBlock>
    </apex:page>
  2. Ensure that your Visualforce page is called with an identifier for a valid account.
Your Visualforce page won’t show much at all except for the account name. Note that the <apex:outputPanel> has been given an identifier named contactDetails. Also note that the <apex:detail> component has a subject attribute specified. This attribute is expected to be the identifier of the record whose details you want to display. The expression {! $CurrentPage.parameters.cid} returns the cid parameter passed to the page. Since you’re not yet passing in such a parameter, nothing is rendered.

Updating Visualforce Pages with Ajax - Visualforce

Visualforce lets you use Ajax effects, such as partial page updates, without requiring you to implement any complex JavaScript logic. The key element is identifying what needs to be dynamically updated, and then using the rerender attribute to dynamically update that region of the pag

Add a Custom Component to a Visualforce Page - Visualforce


You can now use and reference the component you created in the previous lesson much like any standard Visualforce component. The only difference is that instead of usingapex: in the name of the component, you use c:
  1. Create a new Visualforce page called custom.
  2. Use the following as the body of the page:
    <apex:page>
        <c:boxedText borderWidth="1" text="Example 1"/>
        <c:boxedText borderWidth="20" text="Example 2"/>
    </apex:page>
The page simply references the component you created in the previous lesson, twice, each time with different values in the attributes:

A Red Custom Component
Your custom components are automatically added to the help. Click Component Reference and scroll down to <c:boxedText>.

Create a Simple Custom Component - Visualforce


All custom components in Visualforce are wrapped in an <apex:component> component. They typically have named attributes, the values of which you can use in the body of your component. In this lesson, you create a component that uses attributes to determine the contents and width of a red box:
  1. Click Setup | Develop | Components.
  2. Click New.
  3. In the Label and Name text boxes, enter boxedText.
  4. In the Visualforce Markup tab, enter the following:
    <apex:component>
        <apex:attribute name="text" 
               description="The contents of the box."
               type="String" required="true"/> 
        <apex:attribute name="borderWidth" 
               description="The width of the border."
               type="Integer" required="true"/>
     <div style="border-color:red; border-style:solid; border-width:{! borderWidth}px">
     <apex:outputText value="{! text}"/>
     </div>
    </apex:component>
  5. Click Quick Save.
Note how the two attributes are defined to have different types. Visualforce supports a suite of different attribute types and enforces them when someone creates a page that uses the component.
The body of the component can contain other components or simple HTML, as used here—it can also reference the incoming attributes. For example, {! text} is substituted with the value of the text attribute when using the component.

Creating and Using Custom Components - Visualforce


Up until this point you’ve been using standard Visualforce components, such as <apex:dataTable>Visualforce has dozens of these components, but sometimes you’ll want to create your own. For example, you might want to encapsulate your own custom markup and behavior, which you can reuse on many different Visualforce pages.
Unlike the templates in Tutorial #9: Reusing Pages with Templates, custom components can have their own attributes that can change their appearance on the page in which they’re embedded. They can also have complex controller-based logic that executes for that instance of the component. Custom components also automatically become part of the Component Reference help. In short, custom components let you extend Visualforce in whichever direction you see fit.

Include One Visualforce Page within Another - Visualforce

Another way to include content from one page into another is to use the <apex:include> component. This lets you duplicate the entire contents of another page, without providing any opportunity to make any changes as you did with the templates.
  1. Create a new Visualforce page called EmbedsAnother.
  2. Use the following markup in the page:
    <apex:page sidebar="false" showHeader="false">
        <p>Test Before</p>
        <apex:include pageName="MainPage"/> <p>Test After</p>
    </apex:page>
Your original MainPage will be inserted verbatim.

Templates are a nice way to encapsulate page elements that need to be reused across several Visualforce pages. Visualforce pages just need to embed the template and define the content for the placeholders within the template. The <apex:include> component provides a simpler way of embedding one page within another.

Use a Template with Another Page - Visualforce


You can now embed the template in a new page, filling in the blanks as you go.
  1. Create a new Visualforce page called MainPage.
  2. Within the page, add the following markup:
    <apex:page sidebar="false" showHeader="false">
        <apex:composition template="BasicTemplate">
            <apex:define name="body"> <p>This is a simple page demonstrating that this
                   text is substituted, and that a banner is created.</p>
            </apex:define> 
        </apex:composition> </apex:page>
The <apex:composition> component fetches the Visualforce template page you created earlier, and the <apex:define> component fills the named holes in that template. You can create multiple pages that use the same component, and just vary the placeholder text.

Create a Template - Visualforce


Templates are Visualforce pages containing special tags that designate placeholder text insertion positions. In this lesson you create a simple template page that uses the<apex:insert> component to specify the position of placeholder text.
  1. Create a new Visualforce page called BasicTemplate.
  2. Use the following as the body of the page:
    <apex:page>
        <apex:stylesheet value="http://developer.force.com/workbooks/vfdemo.css"/>
        <h1>My Fancy Site</h1>
        <apex:insert name="body"/>
    </apex:page>
The key here is the <apex:insert> component. You won’t visit this page (unless developing it) directly. Rather, create another Visualforce page that embeds this template, inserting different values for each of the <apex:insert> components. Note that each such component is named. In the above template, you have a single insert position named body. You can have dozens of such positions.

Reusing Pages with Templates - Visualforce

Many web sites have a design element that appears on every page, for example a banner or sidebar. You can duplicate this effect in Visualforce by creating a skeleton template that allows other Visualforce pages to implement different content within the same standard structure. Each page that uses the template can substitute different content for the placeholders within the template.

Display Warning and Error Messages - Visualforce

The <apex:pageMessages> component displays all information, warning or error messages that were generated for all components on the current page. In the previous form, the account name was a required field. To ensure that a standard error message is displayed if someone tries to submit the form without supplying an account name, do the following:
  1. Update your page by inserting the following line after the <apex:pageBlock> tag:
    <apex:pageMessages/>
  2. Now click Save on the form. An error panel will be displayed:
    A Warning for a Missing Field


    Visualforce’s standard controllers contain methods that make it easy to save and update records. By using the <apex:form> and <apex:inputField> components, you can easily bind input fields to new records using the standard controllers. The user interface automatically produces input components that match the type of the field—for example displaying a calendar input for a Data type field. The <apex:pageMessages> component can be used to group and display the information, warning and error messages across all components in the page.

    Learning More

    • You can use the <apex:commandLink> instead of the <apex:commandButton> component within a form to provide a link for form processing.
    • Use the quicksave() method instead of the save() method to insert or update an existing record without redirecting the user to the new record.
    • Use the <apex:pageBlockButtons> component to place command buttons when using the <apex:pageBlock> component.
    • Use the <apex:pageMessage> component (the singular, not the plural) to create custom messages.

Show Field Labels - Visualforce


Visualforce does a lot of work behind the scenes, binding the input field to a field on a new record. It can do more, such as automatically showing the field label (much like<apex:outputField> in Tutorial #5: Using Standard User Interface Components), as well as automatically changing the input element to match the data type (for example, showing a picklist instead of an input box).
Modify the contents of the <apex:form> element so that it reads as follows:
<apex:form>
    <apex:pageBlock>
        <apex:pageBlockSection> <apex:inputField value="{!account.name}"/>
            <apex:inputField value="{!account.industry}"/> <apex:commandButton action="{!save}" value="Save!"/>
        </apex:pageBlockSection>
    </apex:pageBlock> </apex:form>
By encapsulating the input fields within <apex:pageBlock> and <apex:pageBlockSection> components, Visualforce automatically inserts field labels (“Account Name”, “Industry”) as well as indicators of whether values are required for the fields, all using the platform styles.

Form with a Field Label

Create a Basic Form - Visualforce


The key to any data input is using a form. In this lesson you’ll create the most basic form.
  1. Create a new Visualforce page called MyForm, which uses a standard controller for the Account object.
    <apex:page standardController="Account">
    </apex:page>
  2. Insert an <apex:form> component, into which all your input fields will be placed:
    <apex:form>
    </apex:form>
  3. Within the form, add an input field for the name field of an account, as well as command button that saves the form when clicked:
    <apex:inputField value="{! account.name}"/>
    <apex:commandButton action="{! save}" value="Save!"/>
This form, although very basic, contains all the essential elements: a form, an input field, and a button that processes the form:
A Sample Form Box
In this case, you use a <apex:commandButton> which produces a button. Note that the action element is bound to {! save}. This expression language syntax looks similar to the syntax you used to specify a field in a record. However, in this context, it references a method—a piece of code named save. Every standard controller automatically supplies a save() method—as well as update() and other methods—so in this case, the save() method on the standard controller is invoked when the button is clicked.
If you enter a value and click Save, the values of the input fields are bound to like-named field values in a new record, and that record is inserted. In other words, the<apex:inputField> component produces an input field for the name field of a new account record, and when you click Save, ensures that the value you entered is automatically saved to that field.
After you click Save, the platform displays the newly-created record. Return to your Visualforce page by entering its URL, which will look something likehttps://na6.salesforce.com/apex/MyForm.

Inputting Data with Forms - Visualforce

In this tutorial you learn how to create input screens using the standard controller, which provides record save and update functionality out of the box. This introduces you to the major input capabilities and their container—the <apex:form> component. Tutorial #13: Creating and Using Custom Controllers extends this and shows how to build forms that interact with your own controllers.

Thursday 6 September 2012

Iterate Using Unstyled Lists and Tables - Visualforce

You have iterated over a list before in Tutorial #5: Using Standard User Interface Components. The <apex:pageBlockTable> component you used produced output that conforms to the standard platform look and feel. Visualforce has a mirror suite of components that allow you to iterate without producing anything other than standard HTML—letting you customize it as you wish.
  1. Add the following to your accountDisplayVisualforce page:
    <apex:dataTable value="{!account.contacts}" var="item">
        <apex:column value="{!item.name}"/> 
        <apex:column value="{!item.phone}"/>
    </apex:dataTable>
    If you don’t see any output, make sure you’re passing the identifier of an account as a parameter. The output will look fairly plain when unstyled, but that’s the point—you can now style this as you wish with standard CSS.
  2. You can also produce a standard HTML unordered list instead of a table by using the <apex:dataList> component. Try this:
    <apex:dataList value="{!account.contacts}" var="item">
        <apex:outputText value="{!item.name}"/>
    </apex:dataList>
  3. If you’d like absolute control, use the <apex:repeat> component that simply iterates. You have to do all the outputting yourself. For example, you can mimic the output of the<apex:dataList> component as follows:
    <ul>
        <apex:repeat value="{!account.contacts}" var="item">
            <li><apex:outputText value="{!item.name}"/></li>
        </apex:repeat>
    </ul>

Style the HTML with CSS - Visualforce


Using standard web techniques, you can add your own CSS to style the page.
  1. Add this just after the <apex:page> tag:
    <style> 
        body {font-family: Arial Unicode MS;}
        h1 {color:red;}  
    </style>
    A Recolored Header Using CSS
    Most web designers don’t embed CSS, but rather reference an external CSS file. You can do this by using the <apex:stylesheet> component.
  2. Replace the complete <style> section you just added with the following:
    <apex:stylesheet value="http://developer.force.com/workbooks/vfdemo.css"/>
    What if you want to host the style files (and accompanying images) themselves on Force.com? You can do that too.
  3. Zip your CSS files up, or download this ZIP file as an example.
  4. Click Setup | Develop | Static Resources | New.
  5. Click New.
  6. In the Name field, enter Style.
  7. In the File field, click Browse and upload your ZIP file (or the one linked to above).
  8. In the Cache Control picklist choose Public.
  9. Now go back to your page and modify your stylesheet component to read as follows:
    <apex:stylesheet value=" {! URLFOR($Resource.Style, 'styles.css')} "/>
The $Resource global variable has a field for each static resource that you upload. In this case it references the static resource named style, which is what you assigned to the ZIP file.URLFOR() is a formula that constructs URLs—in this example from a static resource and an item within that resource. Now you can modify your stylesheets independently of your web pages by simply replacing the static resources.

Remove the Header and Sidebar - Visualforce

Create a new Visualforce page and call it styled, using the following content:
<apex:page standardController="Account">
    <h1>My Styled Page</h1>
    <p>Great!</p>
</apex:page>
Now add a few attributes to the <apex:page> component. Click Save after adding each one to see the effect:
  1. Add sidebar="false"
  2. Add showHeader="false"
    The header and sidebar have now been removed, showing a much more basic page. You need to go one step further to remove all default Force.com styling.
  3. Add standardStylesheets="false"
This ensures that the platform doesn’t add any styling at all to the page.