I’m going to start this post off with a BIG RED CAVEAT:
This makes use of undocumented techniques on the Salesforce platform. This is risky business as platform behaviour may change without notice or warning leading to broken code. You have been warned!
Ok, so the warning aside, I’m going to show you how to ‘hack’ the platform to make those Salesforce detail page buttons render according to rules on the target record.
The motive for this exercise was a conversation I once had with a client who wanted to know if it was easy to disable the buttons based on some criteria on the record to which I replied, ‘No’. I decided at some point I’d have a play around and see if I could come up with a solution that didn’t involve having to write Visualforce pages to replace the standard detail pages by way of a challenge if nothing else. This is the fruit of that which you are free to play around with but only if you heed my caution! 😉
I think Salesforce are missing a trick by not including this behaviour as standard. An ideas posting me thinks.
There are 2 parts to this. One is the logic that determines whether a button should be hidden or not and the other is the actual hiding of the button.
The show/hide logic
This is the simpler part. I decided the easiest way was to create a Custom Object that allows a User or Sys Admin to define which buttons should be hidden by binding the button name to a Checkbox field on the object. If the checkbox is checked then the button should be hidden. Using a checkbox field on the object rather than writing some complex condition parser means the user can simply add a Checkbox formula field and leverage the platforms own condition parser.
The Condition Set custom object below:
It’s a master detail. The header record refers to the SObject API name that we want to add conditions for. The key prefix is the 3 character Id that you can use to determine the object type from an Id. I’ve written trigger to populate this so you only need enter the SObjects API name. I’ve added a few standard button hide fields as well a picklist option to decide whether to Hide or Disable the buttons. For the Standard buttons you need to specify the API name of a checkbox field on the object to bind to. This checkbox must resolve to TRUE in order for the associated button to be hidden. For custom buttons (and other standard buttons) you can add Custom Conditions via the related list. In this case you need to specify the API Name of the Button and the API name of the check box to bind to. There’s no reason why you can’t bind more than one button to the same checkbox either.
The Hiding of the Buttons
Using the Chrome debugging console I worked out the name attribute of the standard buttons, eg. edit, delete, submit, clone. I also found that any custom buttons have a name attribute that matches the API name albeit in lower case. On a detail page the Id of the object being viewed can been obtained from a property pinned on the window object: window.sfdcPage.entityId
So armed with this information I created a Web Service that takes an SObject Id and resolves that to a Condition Set using the SObjects Key Prefix. (The three character code that identifies an SObjects type.) It then queries the SObject itself to determine which buttons to hide using the bound fields from the Condition Set.
One complication arose using the Ajax Toolkit which was where to get the session token from as the Home Page Components don’t have access to any merge fields. I found a trick that Ron Hess had posted up on the Salesforce boards that extracts the Session Id from the page cookie to get round this.
An Account Detail Page with Disabled Buttons
So to show you it in action here’s the Account Detail Page using the above Condition Set:
Cool, now can I see the Code?
To make life easier I’ve uploaded it all into an unmanaged package that you can get here: http://j.mp/1c2R5FF
The package consists of:
- A Trigger: ConditionSetTrigger.trigger – The trigger uses the describe information for the entered SObject API Name to populate the 3 character Key Prefix.
- A Web Service: ConditionSetWebService.cls – The service provides a method that takes an SObject Id and returns the hide button data used by the Home Page Component.
- A Test Class: ConditionSetTests – A couple of unit tests for the service and the trigger.
- 2 Custom objects: Condition Set / Custom Condition – Provide the Condition Set data.
- A Tab: Condition Set – Tab for defining the Condition Sets.
- Install the package.
- Add the Home Page Component to the Home Page Layout. (Setup -> Customize -> Home -> Homepage Layouts)
- Make sure the Sidebar always shows custom components. (Setup -> Customize -> User Interface -> Show Custom Sidebar Components on All Pages)
- Create any Custom Checkbox Fields of Checkbox Formula Fields on the SObjects whose buttons you want to control.
- Create the Condition Sets and bind the Hide Fields to the Checkbox fields on your SObject. Note, when entering API names they must match exactly the API names in your org with namespace prefixes as appropriate.
- Be aware that it uses Google hosted libraries for the jQuery library. Make sure this content is not blocked: //ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
The homepage component code is a bit compressed and unreadable so I’ve provided it here as well in a more tabulated form: