2

So, in the salesforce UI, users can add buttons and links to objects. But I have an app in a visualforce page that I want users to be able to add the same buttons to.

If this is possible, where do you go to add them, then how do you query them and their executable url so I can create the buttons on my page based on what they added?

Is such a thing possible?

2
  • can you provide with an example – Santanu Boral Jul 5 '17 at 19:34
  • I am utilizing events, so I think I can just have the user add any custom button to the event object. But the items in the 'Buttons, Links, and Actions' heading on an object, I want to grab those in my visualforce page, and be able to have the user specify custom buttons for my visualforce page (which may work to have them add them to the event object). – Tyler Dahle Jul 5 '17 at 19:37
1

I didn't know if this was possible or not, so I took a look into it.

Starting off, you should take a look at the $Action global variable. It allows you to, in visualforce (most often in conjunction with something like <apex:outputLink> or <apex:commandButton>), reference buttons, links, and actions on a given object.

The documentation doesn't do a great job of explaining everything you can do with $Action. The typical syntax you'll see is URLFOR($Action.<object name>.<action name>) like URLFOR($Action.Opportunity.New). You can, however, also use array notation to use string literals to specify the object name and action name. Custom buttons/links/actions can also be referenced with $Action

public class TestControllerExtension{
    public String getObjectName(){
        return 'Opportunity';
    }

    public String getActionName(){
        return 'New';
    }
}
<apex:page standardController="Opportunity" extensions="TestControllerExtension">
    <apex:form>
        <!-- Both of these commandButtons are perfectly valid -->
        <apex:commandButton action="{!URLFOR($Action[objectName][actionName])}" />
        <!-- The second parameter to URLFOR is a recordId, and is optional (though
          buttons/links/actions probably won't work correctly without it) -->
        <apex:commandButton action="{!URLFOR($Action['Opportunity']['edit'], Opportunity.Id)}" />
    </apex:form>
</apex:page>

The next step is to figure out how to get a list of button names. It turns out that you can query the Weblink SObject to do this.

For example, to fetch all of the buttons you have on the Opportunity SObject...

[SELECT Id, Name, MasterLabel FROM WebLink WHERE PageOrSobjectName = 'Opportunity']

With the query above, you can present your users with a configuration page where they can select which buttons they want to have included on your App's main visualforce page. You'll need to store user elections somewhere (like a Custom Metadata Type, a Custom Setting, or a full-blown SObject).

At this point, you have all the information you need to display your user-selected buttons in your app's main visualforce page.

The example that I cooked up as a proof of concept doesn't take care of storing/recalling user-selected buttons, but it should serve as a good base for you to work off of.

Controller Extension:

public class TestReassignOLIExtension {
    // Basic setup, declare a variable to store the object instance contained
    //   in the standard controller, and populate it in the constructor
    public Opportunity opp;
    public TestReassignOLIExtension(ApexPages.StandardController con){
        opp = (Opportunity)con.getRecord();
    }

    // I'm returning a List<Weblink> here, and am querying a few extra fields.
    // You don't _need_ to do things this way (and you probably won't), it was
    //   simply convenient for my proof-of-concept.
    // Basically, all we really need is the button name and the MasterLabel
    public List<Weblink> getButtons(){
        // There may be other things that you would want to concern yourself with.
        // DisplayType, for instance, tells you whether a weblink is a button, a link,
        //   or a list button.
        // You may run into issues if you tried to shove a list button into an <apex:outputLink>
        //   for example.
        return [SELECT Id, Name, PageOrSobjectType, LinkType, DisplayType, MasterLabel FROM Weblink WHERE PageOrSobjectType = 'Opportunity'];
    }
}

Visualforce page:

<apex:page standardController="Opportunity" extensions="TestReassignOLIExtension">
<apex:form >
    <!-- apex:repeat allows us to create multiple buttons without repeating markup -->
    <apex:repeat var="button" value="{!buttons}">
        <!-- $Action really isn't useful outside of URLFOR, so far as I can tell.
          The 'Name' field of Weblink is what we use with $Action.
          The 'MasterLabel' contains the 'display name' (as opposed to an API Name)
            and is what normally appears in the buttons when they are included
            in object page layouts -->
        <apex:commandButton action="{!URLFOR($Action.Opportunity[button.Name], Opportunity.Id)}" value="{!buttonName.MasterLabel}"/>
    </apex:repeat>
</apex:form>
</apex:page>
1
  • Great answer! This was the information I was after :). I just was not finding anything useful on how I went about finding the button that belonged to some SObject, but there had to be some way to do so... So the querying the web links got me the information I needed, and your example with the repeat and commandButton are very helpful! Thanks a ton! – Tyler Dahle Jul 5 '17 at 21:09
0

Buttons we create in the Buttons, Links, and Actions are javacript button. That cannot be directly be used in Visualforce page.

You need to create Visualforce buttons using <apex:commandButton> and use that logic behind that.

You may also use HTML buttons <button> or <input type="button"> in Visualforce page.

4
  • Is there a way to get a list of all the buttons from Buttons, Links, and Actions? It will most likely have to be done from Apex I assume. – Tyler Dahle Jul 5 '17 at 20:33
  • From metadata api you will have that – Santanu Boral Jul 5 '17 at 20:35
  • Thank you for the help. My issue now is I have not been able to find any documentation on how to go about accessing those buttons. I have a describe of my object that will hold the custom buttons, but cannot find anything useful in documentations on how to go about getting to the buttons. – Tyler Dahle Jul 5 '17 at 20:39
  • better you can manually add this without going through the Metadata api to fetch custom buttons – Santanu Boral Jul 5 '17 at 20:45

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.