Hiding Custom Buttons on a VisualForce Page

mgsmith | Friday, October 16th, 2009 | 7 Comments »

Sorry it’s been so long time since my last blog post. Life and work just seem to get in the way.

I recently wanted to setup some custom buttons that could be dynamically hidden or renamed on the page. As you probably know, SalesForce.com does not currently have the ability to hide buttons on a page layout. However, it can be done through a combination of VisualForce and JavaScript.

Idea to vote on: http://ideas.salesforce.com/article/show/101209/Limit_the_Visibility_of_a_Custom_Button

The most important thing to note here is that this can only be done on a VisualForce page. It’s not possible to hide or take any actions on custom buttons that are on a standard page. This is due to cross-site scripting limitations of all browsers that prevent JavaScript from modifying the DOM of a window at another domain. You’ll see why as we get into the coding.

To start, I’ve taken a simple custom object and created an even simpler VisualForce page to use for the VIEW. Once created, just override the VIEW option with this page.

<apex:page standardController="Application__c" title="Application For {!Application__c.Contact_Name__c}" >
    <apex:Detail subject="{!Application__c.ID}" relatedList="true" />
</apex:page>

At first, the result is visually the same. Now let’s add a custom button to the page.

Screenshot_NewButton

In this case, I named the button “Update_Status”. The ‘Name’ is critical to modifying the button in the VisualForce. Though, the name must always be lowercase in your VisualForce page. For example, even though I have “Update_Status” as the Name here, my VisualForce code will reference “update_status”.

Now comes the fun. By adding some JavaScript to the VisualForce page you can manipulate the button – hide it, disable it, or even change the button label.

<script>
function hideButton(btnName) {
  try{
    var buttons = parent.document.getElementsByName(btnName);
    for (var i=0; i < buttons.length; i++) {
      buttons[i].className="btnDisabled ";
      buttons[i].disabled=true;
      buttons[i].type='hidden';
    }
  } catch(e) {
    // var ee = e.message || 0; alert('Error: \n\n'+e+'\n'+ee);
  }
}

function renameButton(btnName, newTitle) {
  try{
    var buttons = parent.document.getElementsByName(btnName);
    for (var i=0; i < buttons.length; i++) {
      buttons[i].value=newTitle;
    }
  } catch(e) {
    // var ee = e.message || 0; alert('Error: \n\n'+e+'\n'+ee);
  }
}
</script>

We’ll start with the above two functions. By passing in a button name to the hideButton() function we can hide it on the page. Passing in the same button name and a new title to renameButton() will change the button label on the page. Below is my full VisualForce page code:

<apex:page standardController="Application__c" title="Application For {!Application__c.Contact_Name__c}" >
    <apex:Detail subject="{!Application__c.ID}" relatedList="true" />

<script type="text/javascript">
// The code below is executed as soon as the page loads. Based on the value of the Status__c field
// it either hides or renames the update_status button
if ('{!Application__c.Status__c}' == 'Submitted') renameButton("update_status", "Mark as In-Review");
if ('{!Application__c.Status__c}' == 'In-Review') hideButton("update_status");
if ('{!Application__c.Status__c}' == 'Deposit Pending') renameButton("update_status", "Confirm Deposit Received");
if ('{!Application__c.Status__c}' == 'Deposit Received') hideButton("update_status");
if ('{!Application__c.Status__c}' == 'Approved') hideButton("update_status");
if ('{!Application__c.Status__c}' == 'Rejected') hideButton("update_status");

function hideButton(btnName) {
  try{
    var buttons = parent.document.getElementsByName(btnName);
    for (var i=0; i < buttons.length; i++) {
      buttons[i].className="btnDisabled ";
      buttons[i].disabled=true;
      buttons[i].type='hidden';
    }
  } catch(e) {
    // var ee = e.message || 0; alert('Error: \n\n'+e+'\n'+ee);
  }
}

function renameButton(btnName, newTitle) {
  try{
    var buttons = parent.document.getElementsByName(btnName);
    for (var i=0; i < buttons.length; i++) {
      buttons[i].value=newTitle;
    }
  } catch(e) {
    // var ee = e.message || 0; alert('Error: \n\n'+e+'\n'+ee);
  }
}
</script>

Screen captures of the page with button showing and hidden:

ScreenCapture_WithButtonScreenCapture_WithoutButton

  • Share/Bookmark

7 Comments

  1. frasuy says:

    Nicely done. Pretty slick!

  2. I have been turning buttons on and off using the rendered= property, and by making the button name a value.

    So in the controller, you have variables

    Boolean myButtonOn
    String myButtonName

    You set these in the controller.

    Then, in the Apex page you have

    <apex:commandbutton
    rendered="{!myButtonOn}"
    action="whatever"
    value="{myButtonName}"

    Are there any advantages that you see to either method?

  3. mgsmith says:

    True. I use that when I’m placing the buttons manually onto a completely custom VF page, but in this case I wanted to use the standard Custom Buttons that are defined on an Object and added to a Page Layout. This way the buttons all flow together when using the apex:Detail tag. I think to use the apex:commandButton tag, you’d have to define a new apex:PageBlock above the standard Detail page. Both methods can work.

  4. Kohnejo says:

    It doesn’t work on IE.

  5. Kohnejo says:

    And the reason of it is the “type=’hidden’”. Without this works fine if u dont want them to dissapear, just dont be enabled.

    In my case is fine. Thanks!

  6. AC says:

    Thanks for the blog entry. I’m new to Salesforce and I’m trying to accomplish this. Is it possible to include the full listing for the Custom Button? I’m getting a “button is not defined” message in my attempts to recreate this. Thanks!

  7. mgsmith says:

    AC,

    There is a screen capture of the custom button settings at the top of the post. Feel free to eMail me directly if you need help getting this working in SalesForce.

    Mike

Leave a Reply