Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Friday, August 5, 2011

Using static resources with Salesforce custom Javascript buttons

Having hacked around with Salesforce's custom button that execute javascript, I quickly found myself needing to reuse code across other buttons within our CRM.

Salesforce has a Static Resources repository where you can store images, java script, even zip and jar files. Accessing said resources from the likes of Visualforce pages is a breeze;



Unfortunately, the $Resource variable has not been made available for use in custom buttons. However, we don't really need that variable to get a static resource into our Custom Button. All static resources are accessible via the URL in your salesforce org.

If you navigate to the Static Resources in your salesforce org, and click on the View File link;
You will see that the resource is accessible by a link as follows; https://yourorg.my.salesforce.com/resource/1312307963000/jbUtils

You could include this file directly into your custom button as follows:
{!REQUIRESCRIPT("/resource/1312307963000/jbUtils")}
but the maintainability of this approach will be extremely poor. If you play around with the URL a little more, you will find that the static resource is also available if you remove the string of digits, like this:
https://yourorg.my.salesforce.com/resource/jbUtils
however, this also will cause problems.

See Salesforce does a lot of caching in order to allow their systems to scale. The long string of digits is a cache buster. Every time you update your static resource in Salesforce, a new string of digits will be generated. In fact, the string they use is actually the date & time that you created or updated your static resource represented in Unix Epoch Time and padded out with three trailing zeros.

The $Resources variable takes care of all this magic for us, when used in Visualforce pages, but as it is left out from custom buttons, we need to get creative!

This task would be especially simple if we had some useful time/date functions as part of the Salesforce validation functions, but no such luck. One may think that we could use Javascript date/time functions, but not so fast! The {!REQUIRESCRIPT()} syntax is pre-processed by salesforce, long before it touches your browsers javascript engine.

So, we are left with creating a MacGyver-esque cash buster with the tools that we have. The static resources urls expect to receive a string 17 digits. No letters, hyphens or colons. The closest we can come to is NOW() which will give you a string that looks something like this: '2011-08-06 01:42:00Z' If we strip away the non numeric characters, we get this 20110806014200 which is 14 characters in length. Recall that the URLs expect 17 characters. Using the Salesforce substitution functions, we can create a valid cash buster. Behold the following monstrosity;

{!REQUIRESCRIPT('/resource/' & LEFT(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(TEXT(NOW()),':',''),'-',''),' ',''),10) & '000/jbUtils')}

Now, every time a user visits the page with your custom button, because NOW() always is a new, numerically larger string, the user will always get the freshest-cache-busted static resource available, and you are fee to reuse javascript code in all of your custom salesforce buttons!

Some words of warning; This is a hack, and if this method was to upset our kind Salesforce overlords, we could find the method breaking in the night. Hopefully, said overlords will find our cache-busting-ingenuity charming & cutesy, and reward us by giving us $Resources for our lowly custom buttons...