Hiding Custom Buttons on a VisualForce Page

Note: Jason (aka @tehnrd) posted a very creative solution to hide custom buttons recently. Absolutely worth checking out: http://www.tehnrd.com/show-and-hide-buttons-on-page-layouts/


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