---
schema_version: "1"
id: 3ad0994e52cdb09e06efa7706d68b1ccf6731e2d30d50b81c67d11e84ec9a616
title: Dynamic References to Action Methods Using $Action
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/platform/salesforce-pages-developers-guide/guides/pages/dynamic-vf/pages-dynamic-vf-globals-action.md
canonical_url: https://developer.salesforce.com/docs/platform/salesforce-pages-developers-guide/guide/pages-dynamic-vf-globals-action.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 60d38ea819651312ee46a54c0d569eb53d310fe5571bb43d31667109e84a7510
products:
  - Visualforce Developer Guide
  - Platform Developer Content
---

# Dynamic References to Action Methods Using $Action

The `$Action` global variable allows you to dynamically reference valid actions on an object type, or on a specific record. The most likely way to make use of this is to create a URL to perform that action.

For example, you can use the expression `{!URLFOR($Action[objectName].New)}` in an `<apex:outputLink>`, with a controller method `getObjectName()` that provides the name of the sObject.

Here’s an example that does exactly that. The controller extension queries the system to learn the names of all the custom objects accessible to the user, and presents a list of them, along with links to create a new record. First, create a controller extension named `DynamicActionsHandler`:

<!-- otherprops: extension=DynamicActionsHandler apex_code set_clipboard -->
```controller

public with sharing class DynamicActionsHandler {

    public List<CustomObjectDetails> customObjectDetails { get; private set; }
    
    public DynamicActionsHandler(ApexPages.StandardController cont) {
        this.loadCustomObjects();
    }
    
    public void loadCustomObjects() {
        List<CustomObjectDetails> cObjects = new List<CustomObjectDetails>();
        // Schema.getGlobalDescribe() returns lightweight tokens with minimal metadata
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        for(String obj : gd.keySet()) {
            if(obj.endsWith('__c')) {
                // Get the full metadata details only for custom items
                Schema.DescribeSObjectResult objD = gd.get(obj).getDescribe();
                if( ! objD.isCustomSetting()) {
                    // Save details for custom objects, not custom settings
                    CustomObjectDetails objDetails = new CustomObjectDetails(
                        obj, objD.getLabel(), objD.isCreateable());
                    cObjects.add(objDetails);
                }
            }
        }
        cObjects.sort();
        this.customObjectDetails = cObjects;
    }
    
    public class CustomObjectDetails implements Comparable {
        public String  nameStr   { get; set; }
        public String  labelStr  { get; set; }
        public Boolean creatable { get; set; }
        
        public CustomObjectDetails(String aName, String aLabel, Boolean isCreatable) {
            this.nameStr = aName;
            this.labelStr = aLabel;
            this.creatable = isCreatable;
        }
        
        public Integer compareTo(Object objToCompare) {
            CustomObjectDetails cod = (CustomObjectDetails)objToCompare;
            return(this.nameStr.compareTo(cod.nameStr));
        }
    }
}
```

There are a few things of interest in this extension:

-   The `loadCustomObjects` method uses Apex schema methods to get metadata information about available custom objects. The `Schema.getGlobalDescribe` method is a lightweight operation to get a small set of metadata about available objects and custom settings. The method scans the collection looking for items with names that end in “\_\_c”, which indicates they are custom objects or settings. These items are more deeply inspected using `getDescribe`, and selected metadata is saved for the custom objects.
-   Using `if(obj.endsWith('__c'))` to test whether an item is a custom object or not may feel like a “hack”, but the alternative is to call `obj.getDescribe().isCustom()`, which is expensive, and there is a governor limit on the number of calls to `getDescribe`. Scanning for the “\_\_c” string as a first pass on a potentially long list of objects is more efficient.
-   This metadata is saved in an inner class, `CustomObjectDetails`, which functions as a simple structured container for the fields to be saved.
-   `CustomObjectDetails` implements the Comparable interface, which makes it possible to sort a list of custom objects details by an attribute of each object, in this case, the custom object’s name.

Now create a Visualforce page with the following markup:

<!-- otherprops: apex_page set_clipboard -->
```markup
<apex:page standardController="Account" 
           extensions="DynamicActionsHandler">
    <br/>

    <apex:dataTable value="{!customObjectDetails}" var="coDetails">
        <apex:column >
            <apex:facet name="header">Custom Object</apex:facet>
            <apex:outputText value="{!coDetails.labelStr}"/> 
        </apex:column>
        <apex:column >
            <apex:facet name="header">Actions</apex:facet>
            <apex:outputLink value="{!URLFOR($Action[coDetails.nameStr].New)}" 
                rendered="{!coDetails.creatable}">[Create]</apex:outputLink><br/>
            <apex:outputLink value="{!URLFOR($Action[coDetails.nameStr].List, 
                $ObjectType[coDetails.nameStr].keyPrefix)}">[List]</apex:outputLink>
        </apex:column>
    </apex:dataTable>

</apex:page>
```

On a page that hasn’t been assigned a specific record, the only two useful actions available are `New` and `List`. On a page that queries for a record, the `$Action` global variable provides methods such as `View`, `Clone`, `Edit`, and `Delete`. Certain standard objects have additional actions that make sense for their data types.

**See Also**  


-   [$Action](https://developer.salesforce.com/docs/platform/salesforce-pages-developers-guide/variables/pages-variables-global-action.md)
-   [Valid Values for the $Action Global Variable](https://developer.salesforce.com/docs/platform/salesforce-pages-developers-guide/variables/pages-variables-global-action-valid-values.md)

