No Results
Search Tips:
- Please consider misspellings
- Try different search keywords
Newer Version Available
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:
There are a few things of interest in this extension:
1swfobject.registerObject("clippy.codeblock-0", "9");public with sharing class DynamicActionsHandler {
2
3 public List<CustomObjectDetails> customObjectDetails { get; private set; }
4
5 public DynamicActionsHandler(ApexPages.StandardController cont) {
6 this.loadCustomObjects();
7 }
8
9 public void loadCustomObjects() {
10 List<CustomObjectDetails> cObjects = new List<CustomObjectDetails>();
11 // Schema.getGlobalDescribe() returns lightweight tokens with minimal metadata
12 Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
13 for(String obj : gd.keySet()) {
14 if(obj.endsWith('__c')) {
15 // Get the full metadata details only for custom items
16 Schema.DescribeSObjectResult objD = gd.get(obj).getDescribe();
17 if( ! objD.isCustomSetting()) {
18 // Save details for custom objects, not custom settings
19 CustomObjectDetails objDetails = new CustomObjectDetails(
20 obj, objD.getLabel(), objD.isCreateable());
21 cObjects.add(objDetails);
22 }
23 }
24 }
25 cObjects.sort();
26 this.customObjectDetails = cObjects;
27 }
28
29 public class CustomObjectDetails implements Comparable {
30 public String nameStr { get; set; }
31 public String labelStr { get; set; }
32 public Boolean creatable { get; set; }
33
34 public CustomObjectDetails(String aName, String aLabel, Boolean isCreatable) {
35 this.nameStr = aName;
36 this.labelStr = aLabel;
37 this.creatable = isCreatable;
38 }
39
40 public Integer compareTo(Object objToCompare) {
41 CustomObjectDetails cod = (CustomObjectDetails)objToCompare;
42 return(this.nameStr.compareTo(cod.nameStr));
43 }
44 }
45}- 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:
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.
1swfobject.registerObject("clippy.codeblock-1", "9");<apex:page standardController="Account"
2 extensions="DynamicActionsHandler">
3 <br/>
4
5 <apex:dataTable value="{!customObjectDetails}" var="coDetails">
6 <apex:column >
7 <apex:facet name="header">Custom Object</apex:facet>
8 <apex:outputText value="{!coDetails.labelStr}"/>
9 </apex:column>
10 <apex:column >
11 <apex:facet name="header">Actions</apex:facet>
12 <apex:outputLink value="{!URLFOR($Action[coDetails.nameStr].New)}"
13 rendered="{!coDetails.creatable}">[Create]</apex:outputLink><br/>
14 <apex:outputLink value="{!URLFOR($Action[coDetails.nameStr].List,
15 $ObjectType[coDetails.nameStr].keyPrefix)}">[List]</apex:outputLink>
16 </apex:column>
17 </apex:dataTable>
18
19</apex:page>