Showing posts with label hack. Show all posts
Showing posts with label hack. Show all posts

Wednesday, May 4, 2016

Go to Assembla Ticket

Here's a simple JS code that can be converted into a bookmarklet to quickly open an Assembla ticket.

Tuesday, June 30, 2015

Salesforce Change Set Accelerators

Okay, so this post isn't really about web accelerators in the purest sense of the definition. But if you're frustrated with the experience of navigating and managing change sets in the UI, here are a few quick bookmarklets you can add to your browser to ease the pain.

To "install" a bookmarklet, simply drag the bookmarklet on to your browser's bookmarks bar. Or, in Internet Explorer, right-click the bookmarklet and click Add to favorites...

Last Tested Date: June 30, 2015 (Summer '15)

Change Set: Next


CS > Next

Ever notice that sometimes when you click Next to scroll through the pages of 25 components in a change set, the size of the table shifts and displaces the Next link? This simple bookmarklet clicks the Next link for you, without you having to move your mouse cursor.

Change Set: Previous


CS > Previous

Same as the Change Set: Next bookmarklet, but for the Previous link.

Add to Change Set: more (10,000 records per list page)


AtCS > more (10,000)

When adding components to a change set, especially for something like Custom Fields, you may have noticed two frustrating problems. First, clicking through multiple pages to find the record you want is a pain. Second, multiplying the pain is the fact that what you select on one page is lost when you switch to a different page. This bookmarklet sort of solves the problem by upping the size of the list to 10,000 records, which usually is enough to allow you to select and add all components of the same type at once.

Other tips


If you're planning to create a large change set as you build out your solution over multiple days or weeks, bookmarking the change set's detail page in your sandbox org should be a quick win.

Friday, January 9, 2015

$Action.Contact.AddToCampaign explained

Recently a question came up about using $Action.Contact.AddToCampaign on a Visualforce page. The common usage pattern below for $Action variables does not work as expected.

So, I logged a case with Salesforce to get an explanation for how $Action.Contact.AddToCampaign is supposed to work. And the eventual answer I received after three weeks was very surprising.

In short, the merge variable only works when used as the action value in a form element. Let me illustrate this with the sample Visualforce code below.

The unfortunate answer at this point seems to be that $Action.Contact.AddToCampaign only works if you want to use it inside a custom HTML form, not an apex:form. salesforce.com's recommendation is to use $Action.Campaign.AddCampaign instead, which in my opinion defeats the purpose of easily launching a native wizard to add the contact in a given context to a user-specified campaign.

Tuesday, December 9, 2014

Checkbox field for Live Agent pre-chat form

A [simple question](http://salesforce.stackexchange.com/questions/58529/live-agent-pre-chat-api-custom-checkbox-field/58533#58533) on Salesforce Stack Exchange exposed some unexpected behavior with the Pre-Chat API: Checkbox fields cannot be included as part of the pre-chat form.

The behavior appears to be that if a checkbox field is added to the specification for liveagent.prechat.findorcreate.map and liveagent.prechat.findorcreate.map.doCreate, the creation process fails and the desired record is not created. As soon as the checkbox field is removed from the form definition, the record creation process executes as expected.

While the reason for this behavior is unclear, at least there are two possible workarounds. The key to both workarounds is knowing that the String value of a marked checkbox is "on", and the String value of an unmarked checkbox is blank or null.


Workaround 1: Workflow rule


Assuming you've already created your Checkbox field, you can create a complementary Text field to hold the checkbox value submitted through the pre-chat form. For example, let's say your Checkbox field is named IsEmployed__c. You can create a Text field named IsEmployedText__c, and bind the pre-chat form field to IsEmployedText__c.

To close the loop, you'll create a workflow rule that basically sets IsEmployed__c to true when IsEmployedText__c equals "on", and another workflow rule to set IsEmployed__c to false otherwise.

Workaround 2: Formula field


Start with a Text field, and then simply create a Formula (Checkbox) field that uses NOT( ISBLANK( __ ) ) to produce the equivalent Boolean value.

For example, create a Text field named IsEmployedText__c, and bind the pre-chat form to this field. Within Salesforce, create a Formula (Checkbox) field named IsEmployed__c, and put int he formula NOT( ISBLANK( IsEmployedText__c ) ).

Wednesday, August 20, 2014

Close recurring tasks using Apex

At least one developer had reported encountering an error when trying to automate updates to Task records using Apex: System.UnexpectedException: Apex Task trigger cannot handle batch operations on recurring tasks. This error occurs even in simple scenarios, such as simply closing any open tasks on a close opportunity.

While I agree with what I imagine to be general consensus that this error seems crazy, luckily there appears to be a workaround: Update a custom flag using Apex, and then use workflow rules to handle the dirty work of updating restricted standard field(s).

While I've only tested this approach on the scenario below, I think it will be applicable to solving other similar problems with updating Task records using Apex.

Sample solution to close recurring tasks using Apex


The anonymous Apex code below illustrates the solution.


And there's nothing special about the checkbox field, the workflow rule or the field update. The idea is that when the checkbox is checked, the workflow rule fires and performs the field update.


Monday, May 26, 2014

Last Event or Task Date vs. Last Activity Date

Salesforce gives users the ability to run reports on the Last Activity Date for all objects, out of the box. But what if users wanted to distinguish between Last Event Date vs. Last Task Date? Or break up the data by other criteria?

Luckily, the Declarative Rollups for Lookups package (thanks to Andy Fawcett) can solve this problem, with only a few minor tweaks to work around a Salesforce limitation: field ActivityDate does not support aggregate operator MAX.

The general idea is to create two custom fields on the object of your choice: Last Event Date and Last Task Date. Follow these up with two Lookup Rollup Summaries, and you can now easily split your activity data by Tasks vs. Events. The end result? Reports like the following.


Follow this tutorial and give these new fields a try! Please add a comment below to let me know whether this tip works for you.

Wednesday, April 30, 2014

Custom Button connection.js: INVALID_SESSION_ID

After deploying a custom button from a sandbox to Production, I noticed that the button stopped working. Puzzled, I opened the Web Console in Firefox to find the following error message: INVALID_SESSION_ID.

I was not doing anything special with sforce.connection.sessionId in my code. All the button does is {!REQUIRESCRIPT('/soap/ajax/30.0/connection.js')} and move on to query and update the database. The same code was working fine in my sandbox still, so I figured the next best thing would be to actually look at sessionId to see what's wrong.

At first glance, sessionId looked like a perfectly fine mess of characters that are reasonable for a Session ID value.

00DG0000000krVL!ARQAQP3vNkwdt8OU3WVIjlAwQvWtGcFcIjWq.0jb7A5wYNljj6Oog50.wDma4uUiB.PeDMqx1mLwkMyGj78gyMGLRLGTxic1

Then, I compared sessionId to the sid cookie, and I noticed that the two values were very different.

00DG0000000krVL!ARQAQLWR697R.eqoAy4178kYPxh2kJGv6BOpv_wsHc6KBjY6UPY01.Rfncn6WAMS2klSm.gLvDOWicNKujfE4smTPBLJvyS5

Refreshing the page in my browser did nothing for the problem. The same two values consistently appeared, and the INVALID_SESSION_ID error consistently broke my code.

Finally, the fix was implemented in the form of additional JavaScript in a static resource. This resource, added using REQUIRESCRIPT() after connection.js, simply maps the cookies in the current document and then stores the sid value in sforce.connection.sessionId. The addition of this step resolved the INVALID_SESSION_ID error as far as I could tell.

Has anyone else ever encountered this issue, in Spring '14 or earlier? I feel like I've stumbled upon a bug, because as far as I know connection.js used in a custom button should not need this kind of "initialization".

Monday, February 17, 2014

AJAX Toolkit 29.0 Home Page Component

For orgs trying to push the limits of the standard Home tab in Salesforce, using JavaScript is essential. However, trying to pull in the AJAX Toolkit is not as easy as adding a merge field to a new home page component, because merge fields don't work here. Fortunately, making an assumption about where the toolkit resides allows us to create a home page component that's equivalent to {!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}.

This 1-minute video shows you how to create the component and add it to your home page layout, using the sample code from "Home Page Component: AJAX Toolkit 29.0". The only real "trick" that's needed to make the component work is to extract the session ID cookie and pass it to the sforce object.

Now all of your home page components can be Ajax-enabled.

Wednesday, December 4, 2013

Mark Read Checkbox in Field Permissions for Salesforce Profile with Bookmarklet

Below is a functional bookmarklet that you can use to mark the Read checkbox for every single field in the Field Permissions section of an object's settings within a Salesforce Profile.


To use the bookmarklet:
  1. Drag the link ("bookmarklet") on to your browser's bookmarks bar
  2. Open an object settings page within a Salesforce Profile
  3. Click the bookmarklet in your browser's bookmarks bar

Note: This was tested with Chrome on Windows 8 in Salesforce Winter '14.

Monday, September 2, 2013

Custom CSS for Chatter Communities

Chatter Communities allows an organization using Salesforce to quickly deploy a functional, branded portal experience for partners and customers. Communities conveniently allows for a custom HTML header and footer to be added to a community, but it appears that in the Summer '13 release of Salesforce there is no support for using merge fields or to easily pull in custom CSS styles into a community. If you're used to using the URLFOR() function with the apex:stylesheet element in Visualforce, you may feel like something's missing.

Without too much hacking, there are two HTML5-compliant ways to approach this problem in Summer '13:

<style scoped>...</style>

This approach is simple, and any styles defined should be applied to the div id="contentWrapper" element into which the community's HTML header and footer are inserted. The parent div pretty much includes all of the visual content on the page, which makes this approach fairly comprehensive in the scope of its effects.

JavaScript script to insert link elements

Typically in Visualforce, styles are applied through dynamic links to CSS stylesheets stored as static resources. However, to build that dynamic URL in static HTML requires manual construction based on knowledge of Salesforce's URL conventions.

A relative URL to a CSS stylesheet stored within a .zip file loaded as a static resource has the following components:
  • CommunityName: The keyword appended after ServerName, if applicable. This may be blank for a particular community.
  • ResourceNumber: A unique number assigned to a static resource by Salesforce
  • ResourceName: The name (case-sensitive) of the static resource
  • InsidePath: The path inside the .zip file to the CSS stylesheet
The full URL is then constructed by concatenating the following: '/' + CommunityName + '/resource/' + ResourceNumber + '/' + ResourceName + '/' + InsidePath

A few sample URL's are shown below:
  • /cirruscommunity/resource/1378136101000/CirrusStaticResource/styles/layout.css
  • /slalomcommunity/resource/1379138201002/SlalomStaticResource/css/common.css
ResourceNumber can be ascertained by opening the static resource and looking for the string of numbers in the "View file" link's URL. Right-clicking the "View file" link and copying the link address should easily grab the ResourceNumber for you.

Lastly, the following JavaScript script can be edited to add all of the stylesheets you want to the community.

<script type="text/javascript">
  function appendLinkToHead(path) {
    var link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    link.setAttribute("type", "text/css");
    link.setAttribute("href", path);
   
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(link);
  } // function appendCommunityLink(String)

  var communityName = "community";
  var resourceNo = "1378136101000";
  var resourceName = "CommunityResource";
 
  var resourcePath = "/" + communityName + "/resource/"
      + resourceNo + "/" + resourceName + "/";
 
  var stylesheets = [
      "library/css/brand.css",
      "library/css/layout.css",
      "library/css/reset.css"];

  for (var i = 0; i < stylesheets.length; i++)
    appendLinkToHead(resourcePath + stylesheets[i]);
</script>