Visualforce Pages as Global Custom Actions

Visualforce pages used as global actions can be invoked in many different places and don’t have a specific record associated with them. They have complete freedom of action, which means it’s up to you to write the code.

Required Editions

Available in: both Salesforce Classic and Lightning Experience
Available in: Group, Professional, Enterprise, Performance, Unlimited, Contact Manager, Database.com, and Developer Editions

Visualforce pages you create to use as global actions can’t use a standard object controller. You must write a custom controller to handle the page.

When a global action completes, the user is either redirected to a parent record created as part of the action or returned to where they started.

This code sample shows a Visualforce page designed to be used as a custom action on any object that supports actions. This action lets users create cases from record detail pages, Chatter, Chatter groups (except customer groups), or the home page. It has a different user interface from standard create actions. As with all global actions, the records created through this action aren’t associated with other records.

<!-- Custom controller -->
public with sharing class CreateCaseController {
    public Case theCase {get; set;}
    public String lastError {get; set;}
    public CreateCaseController() {
        theCase = new Case();
        lastError = '';
    }
      
    public PageReference createCase() {
        createNewCase();
        theCase = new Case();
        return null;
    }
       
     private void createNewCase() {      
        try {
            insert theCase;
            
            FeedItem post = new FeedItem();
            post.ParentId = ApexPages.currentPage().getParameters().get('id');
            post.Body = 'created a case';
            post.type = 'LinkPost'; 
            post.LinkUrl = '/' + theCase.id;
            post.Title = theCase.Subject;
            insert post;
        } catch(System.Exception ex){
           lastError = ex.getMessage();
        }
    }   
}

<apex:page controller="CreateCaseController" showHeader="false">
    <script type='text/javascript' src='/canvas/sdk/js/publisher.js'/>
    <style>
        .requiredInput .requiredBlock, .requiredBlock {background-color: white;}
        .custompubblock div {display: inline-block;}
        .custompublabel {width:54px;}
    </style>
   
     <script>
      function refreshFeed() {
          Sfdc.canvas.publisher.publish({name : 'publisher.refresh',  payload : {feed: true}});
      }
     </script>
   
    
    <div>
        <apex:form >
            <apex:actionFunction action="{!createCase}" name="createCase" rerender="out" oncomplete="refreshFeed();"/> 
            <apex:outputPanel id="out" >
                <div class="custompubblock">
                    <div>Subject:&nbsp;</div><apex:inputField value="{!theCase.subject}" style="width:500px;" />
                </div>
                <div class="custompubblock">
                    <div class="custompublabel">Account:</div><apex:inputField value="{!theCase.accountId}" 
                    style="margin-left:0;"/>&nbsp;&nbsp;&nbsp;
                    <div>Contact:&nbsp;</div><apex:inputField value="{!theCase.contactId}" />
                </div>
                <apex:inputField value="{!theCase.description}" style="width:500px;height:92px;margin-top:4px;" />
                <div class="custompubblock" style="margin-top:5px;">
                    <div>Status:&nbsp;</div><apex:inputField value="{!theCase.status}" />&nbsp;&nbsp;&nbsp;
                    <div>Priority:&nbsp;</div><apex:inputField value="{!theCase.priority}" />&nbsp;&nbsp;&nbsp;
                    <div>Case Origin:&nbsp;</div><apex:inputField value="{!theCase.origin}" />
               </div>
                <div style="color:red;">{!lastError}</div>
            </apex:outputPanel>
        </apex:form><br/>
        <button type="button" onclick="createCase();" style="position:fixed;bottom:0px;right:0px;padding:5px 10px; 
        font-size:13px; font-weight:bold; line-height: 
        18px;background-color:#0271BF;background-image:-moz-linear-gradient(#2DADDC, #0271BF);background-repeat:repeat-x;
        border-color:#096EB3;" id="addcasebutton">Create Case</button>
    </div>            
</apex:page>

Requirements for Refreshing Host Pages

To have an object-specific or global custom action refresh the feed on the page that hosts it, the Visualforce page you create to use as that action must:

  • Reference the publisher JavaScript file: <script type='text/javascript' src='/canvas/sdk/js/publisher.js'/>. (Creating custom Visualforce actions doesn’t require the Canvas SDK.)
  • Include this JavaScript call: Sfdc.canvas.publisher.publish({name : 'publisher.refresh', payload : {feed:true}});.