Displaying links to peer objects in Visualforce

I have a custom page that displays one of a collection of child objects of a parent object and wanted to add links that allow the page to switch to any of the other child objects. The code below shows one way to do this, presenting the links as a comma separated list (in a sentence) and showing plain text for the current child object as there is no point in linking to the already displayed page.

The controller (see bottom of this post) has two properties: child which is the current object and children which is the collection of all the child objects with just the Id and Name properties queried.

Here is the Visualforce:

<apex:panelGroup layout="inlined" rendered="{!children.size > 1}">
    <apex:variable var="first" value="{!(true)}"/>
    <apex:outputText>Other child pages </apex:outputText>
    <apex:repeat var="item" value="{!children}">
        <!-- Separator -->
        <apex:outputText rendered="{!!first}">, </apex:outputText>
        <apex:variable var="first" value="{!(false)}"/>
        <!-- Current object's link not clickable -->
        <apex:outputText value="{!item.Name}" rendered="{!item.Id == child.Id}"/>
        <!-- Other object links clickable -->
        <apex:outputLink value="/apex/ChildPage?id={!item.Id}" rendered="{!item.Id != child.Id}">{!item.Name}</apex:outputLink>
    </apex:repeat>
    <apex:outputText>.</apex:outputText>
</apex:panelGroup>

A couple of points to note:

  • The use of an apex:variable to introduce variables into loops such as apex:repeat or apex:pageBlockTable. This code is using a boolean flag; note that without the round brackets true or false are interpreted as controller properties. But a variable can also be used as a loop counter allowing say an item number to be output.
  • The use of an inlined apex:panelGroup – a HTML span – to control the rendering of a set of nested components avoiding having to specify the rendered attribute multiple times on each component.

And here are the properties the controller needs:

// Set from e.g. getRecord method of standard controller
public Child__c[] child {
    get;
    private set;
}
// Peer objects
public Child__c[] children {
    get {
        if (children == null) {
            children = [
                    select Id, Name
                    from Child__c
                    where Parent__c = :child.Parent__c
                    order by Id
                    ];
        }
        return children;
    }
    private set;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s