Quickstart: Creating Custom Actions Using Visualforce

Available in: Salesforce Classic

This was originally part of Developing with the Service Cloud.

Use Case

The time that agents spend clicking through Service & Support is often scrutinized closely. Companies want to enable their agents to be as productive as possible, so if there's a way that few clicks and a few seconds can be saved, it's usually worth investigating. Salesforce.com tries to make the product as efficient as possible out of the box but there's often company-specific type of workflows that salesforce.com could not anticipate. This is where the programmability of the Force.com really shines. Developers can easily extend the user interface to create their own custom buttons that perform unique business logic.


The buttons that are displayed above records like 'New' and 'Clone' are not written in stone. You can easily add your own buttons to perform a custom piece of logic. This is done by going to the Setup screen then clicking Customize | Cases (or whatever object you want) | Buttons and Links. From here you can define a new button. Buttons can do a variety of things such as execute some javascript or load another page. A common use of these buttons is to navigate to a Visualforce page. That page then has a controller associated with it which means that any Apex code can be executed upon load. At this point any kind of data operation could be performed or a custom UI could be displayed.

Sample Code:

This sample Visualforce page accepts a case Id and shows a listing of cases with similar details. This page could be setup to be displayed using a custom "Similar Cases" button. The controller reads the case Id from the query string and then queries for all cases that were created in the last year with the same Reason and Product fields. This is then exposed to Visualforce where the results are displayed in a grid.

Visualforce page:

<apex:page controller="SimilarCasesController" tabStyle="Case">
	<apex:form >
	<apex:sectionHeader title="Similar Cases" subtitle="{!currentCase.CaseNumber}"/>
	<apex:pageBlock title="Similar Cases to {!currentCase.CaseNumber}">
		<apex:pageBlockTable value="{!similarCases}" var="case">
			<apex:column >
				<apex:outputLink value="{!URLFOR($Action.Case.View, case.Id)}">View</apex:outputLink>
			<apex:column headerValue="Case Number" value="{!case.CaseNumber}"/>
			<apex:column headerValue="Owner" value="{!case.Owner.Name}"/>
			<apex:column headerValue="Subject" value="{!case.Subject}"/>
			<apex:column headerValue="Status" value="{!case.Status}"/>


public class SimilarCasesController {
	public Case getCurrentCase() {
		String cid = ApexPages.currentPage().getParameters().get('cid');
		return [SELECT Id, CaseNumber, Reason, Product__c FROM Case WHERE Id = :cid];
	public Case[] getSimilarCases() {
		Case currentCase = getCurrentCase();
		return [SELECT Id, CaseNumber, Owner.Name, Subject, Status FROM Case WHERE 
			CreatedDate >= LAST_N_DAYS:365 AND
			Reason = :currentCase.Reason AND
			Product__c = :currentCase.Product__c AND
			Id != :currentCase.Id];

Further Reading