[SalesForce] Call Global Action in Salesforce1 VisualForce Page

I created a custom VisualForce page to be used in Salesforce1, this page displays events and I have a button to create new events.

This button is currently calling

sforce.one.createRecord('Event')

and it works.
The issue is that in the publisher actions I also added the New Event Global Action with a specific Layout, while the sforce.one.createRecord is using a different Layout.
So to have something consistent I would like the button to call this "New Event" Global Action but I cannot find how to do that.

Best Answer

Unfortunately there isn't currently a way to assign an action to a button. sforce.one.createRecord() uses the standard page layout for the profile/record type, not an action layout.

You could fake it out by creating a Visualforce page that dynamically generates the form based on the action layout, something like this (this is a lead because it's code I had on hand, you can do something similar for your New Event action):

public class QuickCreateController{
    public final ApexPages.StandardController stdController;
    public Lead newLead = new Lead();
    public Map<string, boolean> requiredMap {get;set;}

    public QuickCreateController() {}

    public QuickCreateController(ApexPages.StandardController stdController) 
    { 
        this.stdController = stdController;
        this.newLead = (Lead) stdController.getRecord();

        // Workaround for DescribeLayoutItem.required attribute apparently not
        // accessible in VF page (bug?): storing the required flags in a map.
        requiredMap = new Map<string, boolean>();
    }

    // Get the list of fields in the NewLead global action.
    public List<QuickAction.DescribeLayoutItem> getActionFieldList()
    {
        List<QuickAction.DescribeLayoutItem> fieldList = new List<QuickAction.DescribeLayoutItem>();
        QuickAction.DescribeQuickActionResult[] results = QuickAction.describeQuickActions(new String[]{ QuickAction.NewLead });

        for (QuickAction.DescribeQuickActionResult res : results)
        {
            for (QuickAction.DescribeLayoutRow row : res.getLayout().getLayoutRows())
            {
                for (QuickAction.DescribeLayoutItem col : row.getLayoutItems())
                {
                    // Ignore placeholders.
                    if (!col.placeholder)
                    {
                        fieldList.add(col);

                        // Hack to get DescribeLayoutItem.required flag in the VF page: 
                        // store it in a map, request it from the page.
                        requiredMap.put(col.label, col.required);
                    }                        
                }
            }
        }

        return fieldList;
    }

    public PageReference submitQuickAction()
    {
        PageReference p = new PageReference('/apex/QuickCreate');
        QuickAction.QuickActionRequest req = new QuickAction.QuickActionRequest();
        req.quickActionName = QuickAction.NewLead;
        req.record = newLead;

        try 
        {
            QuickAction.QuickActionResult res = QuickAction.performQuickAction(req);
            p = new PageReference('/apex/Page_To_Go_To_After_Completion);
            p.setRedirect(true);
        }
        catch (Exception ex)
        {
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, ex.getMessage());
            ApexPages.addMessage(myMsg);
        }

        return p;
    }
}

Then your Visualforce page looks something like this:

<apex:page standardController="Lead" extensions="QuickCreateController">
<apex:form >
    <apex:pageMessages />
    <apex:repeat value="{!actionFieldList}" var="layoutItem">
        <apex:outputPanel layout="none" rendered="{!requiredMap[layoutItem.label]}"><span style="font-weight: bold; color: red">*</span> </apex:outputPanel>
        <apex:outputLabel value="{!layoutItem.label}"></apex:outputLabel><br />
        <apex:repeat value="{!layoutItem.layoutComponents}" var="layoutComponent">
            <apex:inputField value="{!Lead[layoutComponent.value]}" required="{!requiredMap[layoutItem.label]}"/>
        </apex:repeat>
    </apex:repeat>
    <apex:commandButton action="{!submitQuickAction}" value="Save" />
</apex:form>
</apex:page>

It's a hack and I don't recommend it as a solution, but I thought it was interesting to know it could be done. :-)

Related Topic