Show and Hide Buttons on Page Layouts
Cloudspokes.com recently wrapped up a challenge titled “Magical Disappearing Salesforce Button with jQuery” and I couldn’t resist not entering. For starters it’s a pretty rad name for a challenge as anything with the words “magical” and “jQuery” in it get me excited. This challenge is now closed for new entries and I’d like to share my submission. Rather than the typical blog type post I’m going to vlog it! This is the first time I have posted something with this much detail so I’d love to get feedback. Are vlogs the way of the future or should I stick to the tried and true formula of written posts? Let me know.
The best way to watch these is to go full screen and the change the playback quality to 720p.
First up is a high level overview:
Next is a 15 minute deep dive that pulls back the covers and gets into all the juicy details.
Cool?!? Want to play with it? Make it better? No problem. Here is a unmanaged package install link to get this setup in your org: https://login.salesforce.com/packaging/installPackage.apexp?p0=04tE0000000HEjD
If you had trouble seeing the markup and script in the video above here is the sidebar html component that makes the magic happen:
<!-- We can locate this div with the script below, traverse up the DOM and then hide the entire sidebar component. --> <div id="sidebarComponentLocator">If you see this, something is broke with Dynamic Button functionality.</div> <!-- Import jQuery from google CDN, could also be static resource--> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> /*Immediately create a unique alias for this version of jQuery to prevent conflicts with other js libraries*/ var j$ = jQuery.noConflict(); /*Determine what type of object is currently being displayed on the page. Only confident way to do this is get object prefix */ var objectPefix = window.location.href.substring( window.location.href.indexOf('.com/') + 5, window.location.href.indexOf('.com/') + 8 ); /*Query the records from Dynamic_Button__c object as soon as possible, don't wait for DOM ready event*/ var result = sforce.connection.query("Select Button_Name__c, Field_Id__c, Field_Value__c from Dynamic_Button__c where Object_Prefix__c = '" + objectPefix + "'"); var records = result.getArray("records"); /*Execute this code block once page DOM has fully loaded*/ j$(document).ready(function(){ /*Hide the sidebar last as this is lowest priority. First priority is show/hiding the buttons. Find the sidebarComponentLocator, then find parent div with class 'sidebarModule' and the hide it*/ j$("#sidebarComponentLocator").closest(".sidebarModule").hide().prev().hide(); /*First loop through the dynamic button records and hide any that are on the layout. We must first hide all the buttons as the Dynamic Button records only contan the 'show' logic*/ for (var i = 0; i< records.length; i++) { /*Hide buttons define in Dynamic_Button__c object*/ j$("input[name='"+ records[i].Button_Name__c.toLowerCase() +"']").hide(); } /*Now loop through the Dynamic_Button_Records and show button if field value matches that define in record*/ for (var i = 0; i< records.length; i++) { /*Get the value from the field on the page layout*/ var recordValue = j$("#"+records[i].Field_Id__c+"_ileinner").text(); var showValue = records[i].Field_Value__c; /*Show the button if the value of the field on this record matchs the setting in the Dyamic_Button__c*/ if(recordValue == showValue){ j$("input[name='"+ records[i].Button_Name__c.toLowerCase() +"']").show(); } } /*Everything above is cool and provides an easy to use interface for the logic but you could always hardcode the logic like so... First get value from the ninja field, this Id would need to be changed var ninjaSkillValue = j$("#00NE0000000d4hc_ileinner").text(); /*Hide Ninja Attack button if Ninja Skill picklist value is not 'High' if(ninjaSkillValue != 'High'){ j$("input[name='ninja_attack']").hide(); } */ }); /*If you are wondering why this file has multiline comments for one one...for some reason single line comments cause the script to break, something funky with salesforce and javascript in the sidebar.*/ </script> |




Good solution, when I saw this challenge on cloud spokes, I thought of including a VF component in layout that can hide the button. But later realized that cross domain script issue will never let this happen. Usage of sidebar for the same is great idea, thanks for sharing !
This will not work in Service cloud console
I’ve done a number of thinks in the left nav before but I haven’t since you could have a collapsible left nav. If the nav is collapsed does the code still execute? I’m guessing it isn’t an ajax call to load the left nav up? As it seems like you have disabled the left nav from collapsing.
nice explanation
. I used a similar approach but instead put all my logic in a class and called by a web service call.
What if salesforce does a upgrade which changes the whole logic in left sidebar? Then this may no longer work. I feel this is more of a hack.
@Francis
Yes it will work even if it is collapsed
@Sandeep, yup you are correct as the sidebar is not loaded on these console pages. I think I heard the sales console is going to be depreciated though, not sure about service console.
@Francis, as mrnoboy said collapsing sidebar has no affect. This is not done with ajax it simply changes the CSS to show and hide the sidebar.
@mrnobody, How did you make the web service call to apex. Did you use my approach or did you find a different way to call make callouts>
Well its almost a similar approach except that i called a class using the apex execute
var StringResult = sforce.apex.execute(“HideButtonClass”,”hideButton”,{Pageurl:Windowlocation});
Using the result, i hid the button.
Also instead of directly taking the value of a field from UI, i queried for the record using SOQL. One more difference is that i used custom setting instead of separate object.
Will mail you the package link via contact page.
Really slick solution!
I had published a blog post a couple of years ago on hiding custom buttons, but that has it’s limitations. Yours is a much more versatile solution. I’ve updated my post to include a link to this one.
http://www.force2b.net/index.php/2009/10/hiding-custom-buttons-on-a-visualforce-page
Wow, that is soo cool! thank you so much for that, you have just saved me hours and hours of work.
Great work J – I wonder what else we could do with this
Awesome !!!!!! U made our job much easy… Heads Off !!
Hello!
Thank you for this great solution!
I also tried to implement it for a customer, but it didn’t work for profiles where the API access is not enabled. Is there a workaround where the solution doesn’t use the API?
Thank you!
Hey Aljoscha,
I think the only way you could do this without API access is to hardcode the logic in the javascript rather than querying it from the custom object.
-Jason
Hi,
I m new to Salesforce and want to implement same functionality in my standard opportunity page layout, the above video are not showing and not able to get anything from the above javascript code, no idea how/where to add sidebar, please help…..
I’m getting the following error message (on Chrome inspector):
Unsafe JavaScript attempt to access frame with URL https://na10.salesforce.com/00QF000000PN2CA from frame with URL https://mkto-si.na10.visual.force.com/servlet/servlet.Integration?lid=066F0000001NxL9&ic=1. Domains, protocols and ports must match
so it doesn’t quite work…
very nice – thankyou!
Hi,
can you tell me how to call apex method from sidebar without using apex page.
with narmal javascript. I am not able to get session id?
thanks in advance.
It’s really helpful ,thanks!
One thing to consider: Loading Jquery in the sidebar may cause issues with VF pages that also load the jquery lib, especially if you’re including different versions.
awesome , awesome , very awesome stuff.. thats what I got to say … thanks for posting this.
does anyone know if this works in winter 13? we are finding that after the upgrade it doesn’t seem to. did SFDC change something in the latest release? curious to hear if other’s are having similar problems
Hi,
It’s really helpful ,thanks!
“Can you help to set inline edit to false using java script.”
Because i am using this functionality for the standard button ” Edit ” i am showing this button based on status picklist( if status equal “XYZ” then show “Edit” button allow user to edit otherwise not). it is also working awesome in my App., but salesforce provide “inline edit” so if i am not showing “Edit” button but still user can edit the data(that i do’t want to) using inline edit functionality.
So to resolve this issue, I have created custom button this will work same as using standard button “edit”. but in custom button i want to put javascript to set inline edit to false.
Please help me, I am in big trouble. need help a fast as soon as possible.
thanks in advance.
@Matt
Yes Matt i am also facing the same problem. If someone find the solution please share.
Hey,
I have implemented this solution and it works perfectly fine but there is one scenario where it doesn’t work. If you change the value of your dropdown from low to high and then cancel it and wont save the changes, it will show you the custom button. Where it should not show you custom button as value is LOW. This is happening because when you click cancel button the whole page doesn’t render. Do you know how I can solve this issue?
Thanks
Ajay
This is amazing, and a piece of functionality I will use again & again.
Thank you.
@vinay
hai i need to remove new button could you please advise??
You can remove the New button with basic Profile based CRUD permissions.
To everyone else having issues I hope take a look in depth soon.
This post was useful. Thank you for your post
Is there a way hide standard buttons from standard page layouts. Like removing the cancel button from the standard page on edit mode.
Please let me know if there is any way to hide them.
Thank You
I have something similar that avoids creating custom objects.
Check it out at:
http://vardhangupta1.blogspot.com/2012/01/hideshow-and-place-custom-button.html
@rehman , @Matt Any news. SF is really new to me, but I want to build an app based on a “home page component” with javascript. Does Winter 13 break this?
@jan, @rehman, @matt is the issue you’re encountering that the homepage component only displays on the home tab not in the sidebar when on the object tab?
i think ultimately i found that the issue was that changing certain fields in the manage section like Name, Button API, Field API looked like they saved (I’d change something and come back and the new values were there) but for whatever reason the functionality broke. It wasn’t until I changed all settings around where it would actually save. very strange.
@Jan yes we are still using this in the Winter 13 release. It can be a bit finicky but we got it working. see my earlier comment about changing things to an existing button you had already created.
Hey,i m doing same in my developer account by installing d unmanaged package you have given n also made d required changes as per your video,but still my not able to hide the button,for both High n Low button is showing.
Help me pls..as i have apply this functionality to my project.
Hey,i m doing same in my developer account by installing d unmanaged package you have given n also made d required changes as per your video,but still my not able to hide the button,for both High n Low button is showing.
Help me pls..as i have to apply this functionality to my project.
Very nice, I had no idea you could control standard SFDC pages like this. This has enabled me to be able to selectively hide Chatter feeds on EVERY page, including the home page, by simply writing a left sidebar HTML component, and then add it to the home page of any profile which you want to selectively exclude from chatter. The component is:
.metadata{ display: none; }
and it works because the name of the class used in the DIV which contains the chatter feed on every page is always ‘metadata’.
@Hamayoun Interested to know why didn’t you just switch it off in the settings? or on the individual objects?
@Francis Sorry if I didn’t make it clear. I’m talking about the case where you may want to use Chatter but only for certain profiles. Out of the box, you get “all or nothing”, and this allows you to make it selective on a profile by profile basis. See this idea here : http://success.salesforce.com/ideaview?id=08730000000GzQAAA0
@Jason, is there a way to use this functionality by checking the value of a checkbox field instead of a picklist? It didn’t seem to work. I set an alert to see what the recordValue and the showValue were in the javascript logic but the recordValue just returns as empty, nothing is displayed. Any thoughts?