15

I have the following command link:

<apex:commandLink value="Edit" action="{!URLFOR($Action.Contact.Edit, rec.id)} />

Which works fine. But I'm trying to make the code generic, to work with multiple objects (not just Contact), so I'd like to specify the action from my controller. Based on the docs for ApexPages.Action, I tried the following:

<apex:commandLink value="Edit" action="{!URLFOR(RecordEditAction, rec.id)} />

With this in the controller:

public ApexPages.Action getRecordEditAction() {
    return new ApexPages.Action('{!$Action.Contact.Edit}');
}

As a test, planning to compute the actual string in the final code. But the test above gives me an "Incorrect argument type for function URLFOR()" error when trying to save the VF page. Looks like ApexPages.Actions are intended to be passed directly as an action param, that is, not via URLFOR, but then there's no way to specify to which object id to apply the action.

How can I specify the desired action from Apex? I don't want to use an url hack (e.g., 003/e); other uses may include delete actions, etc.

6

I think this is what you are looking for:

http://www.salesforce.com/us/developer/docs/pages/Content/pages_dynamic_vf_globals_action.htm

| improve this answer | |
  • 4
    This is what I need. I added an ObjectName property to my controller, and use URLFOR($Action[ObjectName].edit, ...) in my VF Page. Trial and error shows that $Action[ObjectName][ActionName] also works (given a valid ActionName prop value). – Jason Clark Jan 22 '14 at 14:15
  • Your link no longer takes you to the correct documentation. This is why it's best practices to always include the actual text in the answer. – NSjonas Jun 9 at 17:39
6

I don't have a full solution for you but this is one way in which you could get the action for Edit at least:

Controller

private Map<String, PageReference> objectEditActions = new Map<String, PageReference>();

public PageReference GetEditAction()
{
    if(isAccount)
    {
        if(objectEditActions.Get('Account') != null)
        {
            return objectEditActions.Get('Account');
        }

        // presumably you're working with a record since you want to edit it
        Account a = [select Id from Account limit 1];
        PageReference pr = (new ApexPages.StandardController(a)).Edit();
        objectEditActions.Put('Account', pr);
        return pr;
    }
    else if(isContact)
    {
        // same deal
    }
}

Page

<apex:commandLink action="{!GetEditAction}" value="Edit"/>

For a new record I think you'd be limited to using a URL hack or having multiple links in the page that are conditionally rendered based on the object being dealt with. For delete the best bet is to just write a delete action in your controller as it doesn't need an interface like edit does.

| improve this answer | |
  • This may be useful, although in my case I'm displaying links for each record in a list, so I dislike creating a StandardController instance for each record just to get a page ref; additionally, without URLFOR, I can't control other params, such as retUrl. What we really need is an apex version of URLFOR(), but i'd settle for a way to produce $action.<etc> values from apex code. – Jason Clark Jan 22 '14 at 0:09
  • Does your list contain different types of objects, or by generic do you mean the page should be usable with different lists where each item is of the same type? With the could above you can just cache the PageReference to avoid creating multiple controller instances. – Matt Lacey Jan 22 '14 at 0:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.