Home > jQuery, salesforce > Show and Hide Buttons on Page Layouts

Show and Hide Buttons on Page Layouts

January 31st, 2012

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>
Categories: jQuery, salesforce
  1. February 1st, 2012 at 02:09 | #1

    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 !

  2. Sandeep
    February 1st, 2012 at 22:28 | #2

    This will not work in Service cloud console

  3. Francis
    February 2nd, 2012 at 15:44 | #3

    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.

  4. vinay
    February 3rd, 2012 at 02:40 | #4

    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

  5. February 4th, 2012 at 12:11 | #5

    @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>

  6. vinay
    February 4th, 2012 at 19:04 | #6

    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.

  7. Mike
    February 10th, 2012 at 09:34 | #7

    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

  8. February 13th, 2012 at 20:06 | #8

    Wow, that is soo cool! thank you so much for that, you have just saved me hours and hours of work.

  9. March 1st, 2012 at 01:20 | #9

    Great work J – I wonder what else we could do with this ;)

  10. pchadha
    March 3rd, 2012 at 21:40 | #10

    Awesome !!!!!! U made our job much easy… Heads Off !!

  11. Aljoscha
    April 11th, 2012 at 06:32 | #11

    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!

  12. April 15th, 2012 at 14:29 | #12

    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

  13. Anil D
    April 19th, 2012 at 07:03 | #13

    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…..

  14. Itay
    June 12th, 2012 at 01:21 | #14

    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…

  15. pure
    June 16th, 2012 at 05:06 | #15

    very nice – thankyou!

  16. PP
    July 17th, 2012 at 06:50 | #16

    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.

  17. Reetika Budhiraja
    July 23rd, 2012 at 23:37 | #17

    It’s really helpful ,thanks!

  18. August 5th, 2012 at 09:11 | #18

    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.

  19. PP
    August 5th, 2012 at 16:29 | #19

    awesome , awesome , very awesome stuff.. thats what I got to say … thanks for posting this.

  20. Matt
    September 13th, 2012 at 08:12 | #20

    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

  21. Sandeep dobariya
    September 21st, 2012 at 22:31 | #21

    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.

  22. rehman
    September 24th, 2012 at 03:53 | #22

    @Matt
    Yes Matt i am also facing the same problem. If someone find the solution please share.

  23. Ajay
    September 25th, 2012 at 12:35 | #23

    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

  24. Sarah
    October 8th, 2012 at 01:06 | #24

    This is amazing, and a piece of functionality I will use again & again.

    Thank you.

  25. yamuna
    October 9th, 2012 at 07:43 | #25

    @vinay

    hai i need to remove new button could you please advise??

  26. October 9th, 2012 at 07:46 | #26

    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.

  27. Kranthi
    October 12th, 2012 at 20:06 | #27

    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

  28. October 19th, 2012 at 23:45 | #28

    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

  29. November 3rd, 2012 at 13:16 | #29

    @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?

  30. Phil
    December 19th, 2012 at 07:42 | #30

    @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?

  31. Matt
    December 19th, 2012 at 08:05 | #31

    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.

  32. Matt
    December 19th, 2012 at 08:07 | #32

    @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.

  33. VK SIngh
    January 15th, 2013 at 22:01 | #33

    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.

  34. VK SIngh
    January 15th, 2013 at 22:25 | #34

    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.

  35. Hamayoun
    February 12th, 2013 at 09:43 | #35

    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’.

  36. February 13th, 2013 at 02:20 | #36

    @Hamayoun Interested to know why didn’t you just switch it off in the settings? or on the individual objects?

  37. Hamayoun
    February 13th, 2013 at 09:45 | #37

    @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

  38. Josh
    March 13th, 2013 at 12:18 | #38

    @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?