Quickstart: Creating Compound Views Using Visualforce

Available in: Salesforce Classic

This was originally part of Developing with the Service Cloud.

Use Case

One of the most important aspects of salesforce.com's Service & Support is how it enables agents to be efficient in their dealings with support cases. One of the biggest factors in efficiency is the time it takes for agents to navigate through various records related to a particular case. This navigation time can be greatly reduced by presenting multiple views of related records on a single screen. A salesforce.com feature called Consoles does this and now with the introduction of Visualforce, developers can build their own compound collection of views with ultimate flexibility.

Background

While Visualforce enables ultimate power and flexibility, that doesn't come at the cost of having to create everything from scratch. There are in fact dozens of standard components that come with Visualforce that represent many of the common elements that comprise data-centric user interfaces. From page headers to tab bars to data grids and buttons, Visualforce developers can build apps that leverage the same building blocks that salesforce.com itself uses for it's own Service & Support application. The real value shines through when you can compose a page that uses all this out-of-the-box code but tie it together with your own custom logic. Which fields should be displayed in the grid? What should that link do when clicked? It's all up to you.

Sample Code: Simple Compound View

This sample Visualforce page and controller provide a simple view of all cases assigned to the current user. When a 'View' link is clicked next to a case, all the case details are shown. In addition, below that data a table is displayed showing all solutions that might apply to those cases. The fairly small amount of code illustrates how much can be accomplished using the standard Visualforce components.

Visualforce page:

<apex:page controller="MyConsoleController">
	<apex:form >
	
	<apex:sectionHeader title="Cases Cockpit"/>
	
 	<div id="caseInfo" style="float:left;width:25%">
		<apex:pageBlock title="My Cases">
			<apex:pageBlockTable value="{!myCases}" var="case">
				<apex:column >
					<apex:commandLink value="View" action="{!viewCase}">
						<apex:param name="caseId" value="{!case.Id}"/>
					</apex:commandLink>
				</apex:column>
				<apex:column headerValue="Subject" value="{!case.Subject}"/>
				<apex:column headerValue="Status" value="{!case.Status}"/>
			</apex:pageBlockTable>
		</apex:pageBlock>
	</div>
	
	<div style="float:right;width:73%">
		<apex:detail id="caseDetail" subject="{!selectedCase.Id}" relatedList="false" title="false"/>
	</div>
	
	<div style="width:100%">
		<apex:pageBlock title="Solutions">
			<apex:pageBlockTable value="{!solutions}" var="sol">
				<apex:column >
					<apex:commandLink value="View" action="{!viewSolution}">
						<apex:param name="caseId" value="{!sol.Id}"/>
					</apex:commandLink>
				</apex:column>
				<apex:column headerValue="Solution #" value="{!sol.SolutionNumber}"/>
				<apex:column headerValue="Name" value="{!sol.SolutionName}"/>
				<apex:column headerValue="Status" value="{!sol.Status}"/>
			</apex:pageBlockTable>
		</apex:pageBlock>
	</div>
		
	</apex:form>
</apex:page>

Controller:

public class MyConsoleController {

	public Case selectedCase { get; set; }
	
	public Solution[] getSolutions() {
		return [SELECT Id, SolutionNumber, SolutionName, Status FROM Solution];
	}
	
	public Case[] getMyCases() {
		return [SELECT Id, Subject, Status FROM Case WHERE OwnerId = :UserInfo.getUserId()
			AND Status != 'Closed'];
	}
	
	public PageReference viewCase() {
		String caseId = ApexPages.currentPage().getParameters().get('caseId');
		selectedCase = [SELECT Id FROM Case WHERE Id = :caseId];
		return null;
	}
	
	public PageReference viewSolution() {
		String solId = ApexPages.currentPage().getParameters().get('solId');
		return new PageReference('/' + solId);
	}
}

Further Reading