Monday, April 6, 2015

Enable / Disable Buttons on Standard Detail Page

In Salesforce.com we always have 2 ways to implement a requirement or use case. One is Declarative "or" Point-And-Click tools and if any thing which we can not implement then we consider to go with another way which is Programmatic using Apex, Visualforce, SOQL, SOSL or Salesforce API's.

Here I am going to take one of the use case which I came across during implementation. A customer wanted to show custom buttons on Opportunity detail page and based on each button click they wanted to perform some actions on an Opportunity record (e.g. Update Stage field etc.). This can be achieved easily using Declarative "or" Point-And-Click tools. However they also wanted to Enable or Disable those Custom Buttons based on the value of Stage field in Opportunity record. This is something you cannot achieve via standard OOTB (out-of-the-box) features of Salesforce.com. So, now what to do?

Now lets take a specific example here. For example you have 3 custom buttons with following Name:

  • Prospecting
  • Closed Won
  • Closed Lost
To create a custom button Go to, Setup > Build > Customize > Opportunities > Buttons, Links, and Actions

After creating custom buttons, add them in Page Layouts of Opportunity.

To enable / disable those buttons on standard detail page of Opportunity, we need to override the standard detail page with a Visualforce page.

A Visualforce page must be using "Opportunity"  as a standard controller and an Apex class "OpportunityCustomButtonsCtrlExt" as a visualforce controller extension.

First, create an Apex class. To create an Apex class Go to, Setup > Build > Customize > Develop > Apex Classes > New

Now copy and paste below code into the Apex class editor and Save it.

Visualforce Controller Extension Code

              --------------------------------------------------------------------------------------------
public with sharing class OpportunityCustomButtonsCtrlExt{

    private boolean buttonProspecting;
    private boolean buttonClosedWon;
    private boolean buttonClosedLost;
    
    public Opportunity opportunityRecord {get; private set;}
    
    public boolean getButtonProspecting(){
        return buttonProspecting;
    }
    public boolean getButtonClosedWon(){
        return buttonClosedWon;
    }
    public boolean getButtonClosedLost(){
        return buttonClosedLost;
    }

    public OpportunityCustomButtonsCtrlExt(ApexPages.StandardController stdController) {
        this.opportunityRecord = (Opportunity)stdController.getRecord();
        enableDisableCustomButtons();
    }
    
    private void enableDisableCustomButtons(){
        // IF Stage = Prospecting THEN 
        // disable Prospecting button and enable Closed Won and Closed Lost buttons
        if(opportunityRecord.StageName == 'Prospecting'){
            buttonProspecting = true;
            buttonClosedWon = false;
            buttonClosedLost = false;
        }
        // IF Stage = Closed Won or Closed Lost THEN 
        // enable Prospecting button and disable Closed Won and Closed Lost buttons
        else{
            buttonProspecting = false;
            buttonClosedWon = true;
            buttonClosedLost = true;
        }
   }

}
              --------------------------------------------------------------------------------------------


To create a Visualforce page Go to, Setup > Build > Develop > Pages

Now copy and paste below code into the Visualforce page editor and name this Visualforce page as "OpportunityCustomButtonsPage" and Save it.

Visualforce Page Code

--------------------------------------------------------------------------------------------
<apex:page standardController="Opportunity" extensions="OpportunityCustomButtonsCtrlExt">

    <!-- This will render a standard detail page of Opportunty with all related lists -->
    <apex:detail subject="{!Opportunity.Id}" relatedList="true" title="true" showChatter="true" inlineEdit="true" oncomplete="javascript:location.reload();"  />

    <!--
        This is because we do not need to query Stage field in associated Controller Extension class
        because we are using getRecord() method of Standard Controller. If you will not use below line
        then you will need to query Stage field otherwise you will get an error saying:
        SObject row was retrieved via SOQL without querying the requested field: Opportunity.StageName 
    -->
    <apex:outputText value="{!Opportunity.StageName}" rendered="false"></apex:outputText>
    
    <script type="text/javascript">
    
    function checkButtonName(){
        if('{!buttonProspecting}' == true || '{!buttonProspecting}' == 'true') {
            // prospecting is an API Name of the custom button Prospecting
            // make sure you all letters must be small
            enableDisableButtons("prospecting");
        }
        if('{!buttonClosedWon}' == true || '{!buttonClosedWon}' == 'true'){
            // prospecting is an API Name of the custom button Closed Won
            // make sure you all letters must be small
            enableDisableButtons("closed_won");
        }
        if('{!buttonClosedLost}' == true || '{!buttonClosedLost}' == 'true'){
            // prospecting is an API Name of the custom button Closed Lost
            // make sure you all letters must be small
            enableDisableButtons("closed_lost");
        }
    }
    
    checkButtonName();
    function enableDisableButtons(btnName1) {
      try{
        var buttons = document.getElementsByName(btnName1);
        for (var i=0; i < buttons.length; i++) {
          buttons[i].className="btnDisabled ";
          buttons[i].disabled=true;      
        }
      } catch(e) {
      }
    }
    
    </script>

</apex:page>
                   --------------------------------------------------------------------------------------------


Now the last and final step is to override / replace detail page of Opportunity with a Visualforce page "OpportunityCustomButtonsPage" which you just created.

To override Detail View of Opportunity Go to, Setup > Build > Customize > Opportunities > Buttons, Links, and Actions > click "Edit" associated to View > select a Visualforce page "OpportunityCustomButtonsPage" from the drop-down menu  > click Save


Now Opportunity page should look like this:

IF Stage = Prospecting




IF Stage = Closed Won "or" Closed Lost