Visualforce Development Cookbook
上QQ阅读APP看书,第一时间看更新

The custom iterator component

The Visualforce standard component <apex:repeat /> iterates a collection of data and outputs the contained markup once for each element in the collection. In the scenario where this is being used to display a table of data, the markup for the table headings appears before the <apex:repeat /> component and is rendered regardless of whether the collection contains any records or not.

Custom iterator components may contain additional markup to be rendered outside the collection, for example, the headings markup in the scenario mentioned earlier. This allows the component to avoid rendering any markup if the collection is empty through the logic implemented in a custom controller.

In this recipe, we will create a custom component that takes a collection of data and renders a containing page block and a page block section for each element in the collection. If the collection is empty, no markup will be rendered. We will also create a containing page that displays the details of an sObject account and utilizes the custom component to display contact and opportunity information, if present.

Getting ready

This recipe makes use of a custom controller, so this will need to be present before the custom component can be created.

How to do it…

  1. Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
  2. Click on the New button.
  3. Paste the contents of the AllOrNothingController.cls Apex class from the code download into the Apex Class area.
  4. Click on the Save button.
  5. Navigate to the Visualforce Components setup page by clicking on Your Name | Setup | Develop | Components.
  6. Click on the New button.
  7. Enter AllOrNothingPageBlock in the Label field.
  8. Accept the default AllOrNothingPageBlock that is automatically generated for the Name field.
  9. Paste the contents of the AllOrNothingPageBlock.component file from the code download into the Visualforce Markup area and click on the Save button.
  10. Next, create the custom controller for the Visualforce page by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
  11. Click on the New button.
  12. Paste the contents of the AllOrNothingListsExt.cls Apex class from the code download into the Apex Class area.
  13. Click on the Save button.
  14. Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
  15. Click on the New button.
  16. Enter AllOrNothingLists in the Label field.
  17. Accept the default AllOrNothingLists that is automatically generated for the Name field.
  18. Paste the contents of the AllOrNothingLists.page file from the code download into the Visualforce Markup area and click on the Save button.
  19. Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
  20. Locate the entry for the AllOrNothingLists page and click on the Security link.
  21. On the resulting page, select which profiles should have access and click on the Save button.

How it works…

Opening the following URL in your browser displays the AllOrNothingLists page: https://<instance>/apex/AllOrNothingLists?id=<account_id>.

Here, <instance> is the Salesforce instance specific to your organization, for example, na6.salesforce.com, and <account_id> is the ID of an account from your Salesforce instance.

The page displays brief details of the account and page blocks for the account's contacts and opportunities.

If the account does not have any opportunities or contacts, the appropriate page block is omitted.

The AllOrNothingPageBlock custom component accepts a list of generic sObjects and wraps its content in an output panel that is only rendered if the list is not empty.

<apex:outputPanel rendered="{!render}">
      <apex:pageBlock title="{!title}">
        <apex:repeat value="{!list}" var="ele">
          <apex:componentBody >
            <apex:variable var="{!var}" value="{!ele}"/>
          </apex:componentBody>
        </apex:repeat>
      </apex:pageBlock>
  </apex:outputPanel>

The <apex:componentBody /> defines where the content from the Visualforce page will be inserted. As this is inside the <apex:repeat /> component, this insertion will take place for each element in the collection.

The Visualforce page passes attributes to the component of the list to iterate the title of the page block, and the variable name representing an element in the list. The contained markup can reference the variable name to access fields or properties of the element.

<c:AllOrNothingPageBlock list="{!opportunities}" var="opp"
       title="Opportunities">
<apex:pageBlockSection title="{!opp.Name}">
      <apex:outputField value="{!opp.Amount}" />
      <apex:outputField value="{!opp.CloseDate}" />
      <apex:outputField value="{!opp.StageName}" />
      <apex:outputField value="{!opp.Probability}" />
</apex:pageBlockSection>
</c:AllOrNothingPageBlock>