Apex Code ButtonLet’s say you want to execute Apex code from a detail page button in Salesforce. Yes, you can do this with JavaScript and the Ajax toolkit. However, JavaScript is tricky — it can vary its behavior from browser to browser, and relies on client-side processing. While this approach is functional, it is not always perfect.

An easier, more consistent approach is to use VisualForce as a framework for adding Apex logic to a button. This requires about the same amount of VisualForce knowledge as the JavaScript approach does JavaScript knowledge, which is to say, “not very much.” It also involves the same level of copying and pasting skills, which I know you probably have in abundance.

In the following example, we’ll create a button on the Account object, and the logic behind this button will set the industry on the account to “Spice Trading” and reload the page. This pattern will work for any object, and can contain any Apex logic you need for your application.

Step 1: Create a Simple VisualForce Page

To create a VisualForce page in the Developer Console, click your name | Setup | Developer Console, then click Repository (the tab), select Pages on the top left, and then click New.

Name the page “ApexButtonPage”. The page source is the following single line:

<apex:page standardController="Account" extensions="ApexButtonPageController" action="{!doMyApexLogic}" />

Step 2: Create a Simple VisualForce Controller Extension

From the Developer Console Repository tab, to create an Apex class select Classes in the top left and click New.

Name the page “ApexButtonPageController”. We referred to this name in the page definition you copied from above, so make sure they match.

Here is the source for the class:

public class ApexButtonPageController {
    Account theAccount;

    public ApexButtonPageController(ApexPages.StandardController stdController) {
        // get the current Account
        theAccount = (Account)stdController.getRecord();
    }

    public PageReference doMyApexLogic() {
        //whatever logic you want
        //<demo logic>
        theAccount.Industry = 'Spice Trading';
        update theAccount;
        //</demo logic>
        return new PageReference('/' + theAccount.id);
    }
}

Step 3: Add a Button to the object

This can be done using the standard UI. Do this how ever you are comfortable, or try one of these paths.

For standard objects, go to setup -> customize -> whichever -> buttons and links, and click “New”.

For custom objects, go to setup -> create -> objects, click the object, and scroll down to “Custom Buttons and Links” and click “New”.

Step 4: Configure your button

  • For “Display Type”, this example uses a “Detail Page Button”.
  • For “Behavior”, select “Display in existing window with sidebar”.
  • For “Content Source”, select “VisualForce Page”. In the “Content” dropdown that appears, select “ApexButtonPage”.

Step 5: Add the button to the page layouts

You can do this in the UI layout editor.

Step 6: Test it out

  • Open an Account record
  • Click the new button
  • Watch the page reload, with “Spice Trading” as the industry.

Step 7: Marvel at your accomplishment!

You should be able to recreate this for any logic you need in your system as the target of a detail page button or link.

For a list button, you will need to implement the extension with the ApexPages.StandardSetController. This will be slightly more complex, as you’ll have access to multiple objects, and to the records selected when the button is clicked.  Please see the VisualForce Reference guide for more information on the StandardSetController and its methods.

More Knowledge

Now that we’ve succeeded, let’s break down what VF is doing to enable this behavior.

The page is quite simple, with just one line to it. This is because it’s never going to appear on the screen – we’ll redirect back to the object detail page right away. There are three key aspects to the page tag.

  1. The “standardController” parameter allows you to get access to the object from which the button was called.
  2. The “extensions” parameter identifies our class as an extension to be called.
  3. The “action” parameter identifies the function in our class that calls the Apex logic we want to execute.

 

The extension is also fairly simple.

  1. The constructor is able to access the record the user was viewing when pressing the button. We store that in a member variable.
  2. The action function performs the required logic (in our case, updating the industry field).
  3. After this, the action function redirects the browser to the object detail page following the update.

 

That is all there is to it! Now you know more, and you are a better developer. Happy coding!

tagged , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://twitter.com/andyinthecloud Andrew Fawcett

    Great article Josh! So often still overlooked these days. Other downside with the older JavaScript button approach is you have to create an Apex WebService for the JS to call, which means ‘global’ methods, which means, well you get the idea…. not great overhead for a simple button logic! Anyway, once again, great article!

    • SFDCUser

      Does it have any implications with package security reviews when you have DML statements in your apex controller and method is called from pageAction

  • crop1645

    Suppose there are validation errors or trigger add.error statements executed in the course of the ‘update theAccount;’ statement? Will those errors be displayed upon the return from doMyApexLogic?

    • Aaron Clancy

      Anyone know of a clean way to handle this? Without proper validation errors then this method should be avoided.

  • Vardhan Gupta

    I have extended this concept to allow to ‘hide and show’ buttons on a standard layout based on a certain logic using formula fields. One can read the solution on my blog