Posts in Category: Salesforce

How to define filename for a Visualforce generated PDF (renderAsPdf) ?

When rendering a visualforce page as a PDF, the filename of the PDF (by default) is the name of the page which may be annoying at times. Annoying as every time the file is generated, it will be generated with same name and will lead to cause confusion with the user. If opened multiple times, files will be saved as invoice.pdf, invoice[1].pdf, invoice[2].pdf … and so on. Ideally you should be able to define the name of the generated PDF but that’s not something well documented anywhere.

To rescue (as always) comes Salesforce blogs/forums [1][2].

In order to set filename for generated PDF you need to set the Content-Disposition header. In constructor of the Visualforce controller use below code:

Apexpages.currentPage().getHeaders().put('content-disposition', 'attachment; filename=AccountReport.pdf'); //In case you want to download pdf

or
Apexpages.currentPage().getHeaders().put('content-disposition', 'inline; filename=AccountReport.pdf'); //In case you want to open pdf in browser

Please Note : If you want to make the file name dynamic you will need to refer to several RFCs on how to correctly encode the filename. E.g. if it contains spaces it will need to be quoted. If there are non-ASCII characters or it is longer than 78 characters it needs to be Hex encoded (RFC 2184).

References
[1] https://salesforce.stackexchange.com/questions/4118/how-can-i-specify-a-file-name-for-a-visualforce-generated-pdf
[2] https://developer.salesforce.com/forums/ForumsMain?id=906F000000095BPIAY

Visualforce Jquery Select List with Search feature

Lets say you have a requirement where-in you are displaying a select-list (picklist) on a visualforce page for user selection. Based on user selection you are doing some operation. Now if this select list is too big (i.e., is list of  50+ items), then its really hard to select a particular item as visualforce select list doesn’t support searching of options inside a select list.

Inorder to provide similar functionality, I google’d and found a really nice jquery plugin – Chosen. Convert long, unwieldy select boxes much more user-friendly.

Below is simple to follow steps to incorporate same in a visualforce page.

Step1 : Import necessary Jquery+Chosen JS & CSS into Static Resource. Download @ https://github.com/harvesthq/chosen/releases

Step2 : Include above imported js and css in visualforce page

<!– Include Chosen JQuery Plugin Javascript and CSS Files –>
<apex:includeScript value=”{!URLFOR($Resource.chosen_jquery_plugin, ‘chosen.jquery.js’)}”/>
<apex:includeScript value=”{!URLFOR($Resource.chosen_jquery_plugin, ‘chosen.jquery.min.js’)}”/>
<apex:includeScript value=”{!URLFOR($Resource.chosen_jquery_plugin, ‘docsupport/prism.js’)}”/>
<apex:stylesheet value=”{!URLFOR($Resource.chosen_jquery_plugin, ‘docsupport/prism.css’)}”/>
<apex:stylesheet value=”{!URLFOR($Resource.chosen_jquery_plugin, ‘chosen.css’)}”/>

Step3: Include script to convert select into select with search

<script>
j$ = jQuery.noConflict();
j$(document).ready(function() {
j$(“select[id*='IdOfSelectElement']“).chosen();
});
<script>

Salesforce – Generating Stub Code(Jar) from a WSDL

When integrating any non native application (JAVA or NET or ..) with salesforce, you need to have the salesforce API library in place that can be referred/used as a referenced library in project being developed. This library is the the one that acts as face to salesforce i.e., intermediary between your application and salesforce.

Simple yet important step of such type of integration is to generate stub code (jar file) from wsdl (salesforce enterprise or partner wsdl) and though such a simple step, we (at least I) always forget (or I should say cant recall easily) the step on how to generate same.

Below are three easy steps to generate stub code (jar) from a wsdl:

  1. Download Enterprise (Partner) WSDL by navigating to Setup -> API – > Enterprise (Partner) WSDL (right click and save file as “abc.wsdl”, ensure extension “.wsdl” is there).
  2. Download Force.com Web Service Connector (WSC) [1]. The Force.com Web Service Connector (WSC) is a high performing web service client stack implemented using a streaming parser. WSC also makes it much easier to use the Force.com API (Web Services/SOAP or Asynchronous/REST API). You can download a pre-built WSC jar file from: http://code.google.com/p/sfdc-wsc/downloads/list
    Now generate Stub Code from a WSDL. Run wsdlc on the WSDL you have downloaded:

    java -classpath wsc-xx.jar com.sforce.ws.tools.wsdlc *wsdl* *jar.file*
    or
    java -jar wsc-23.jar *wsdl* *jar.file*

    wsdl is the name of the WSDL file
    jar.file is the name of the output jar file that wsdlc generates
    You can include an optional argument: -Dpackage-prefix=myprefix

  3. Now write your client application. Add wsc-xx-min.jar and jar.file (generated by wsdlc) to your classpath, then compile and run your client application.

With this you are all set with stub code / library and ready to make soap API calls to Salesforce.

Enjoy Coding!

References:
[1] https://code.google.com/p/sfdc-wsc/

Javascript (jQuery) code to fetch Salesforce Lead Convert Custom Field Mappings (in terms of API Names)

Yesterday came across a requirement to list down Lead Convert Custom Field Mappings in terms of API Names ie Lead Field1__c maps to Account/Contact/Opportunity Field1__c. Salesforce UI doesn’t give that option to extract same. Neither any metadata API got that, really strange that there’s no way I can extract Lead Convert Custom Field Mappings (in terms of API Names). Is there any? please help in case I’m missing some standard way of extracting that out?

Easiest option could have been that I sit down and do manual and tedious way of reading each field label finding its API Name and record the same in excel, but this doesn’t seem viable option for an org with 100+ lead convert field mappings. As I couldn’t find one using all standard approaches, I started thinking of wicked ways of achieving it. And as usual Javascript (jQuery) comes to rescue party!

Login to Salesforce Org in Chrome or FF Browser,
Navigate to lead convert field mappings page (Select Your Name | Setup | Customize | Leads | Fields | Map Lead Fields),
Open Javascript Console,
Now load jQuery first (you can do same by loading any existing jQuery booklet or userscript too) by executing below code in JS Console.


var jq = document.createElement('script');
jq.src = "//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
$j=jQuery.noConflict();

Now comes the main code which will output LeadFieldAPIName, Account/Contact/Opportunity Field APIName, Account or Contact or Opportunity. Execute below code too in JS Console.

//Traverse across all Select elements
$j("select").each(function () {

//Consider only the ones with a mapping selected
if (this.value != '') {

//Fetch Object Name to which this particular Lead field is mapped, whether its Account or Contact or Opportunity
var objectname = $(this).find('option:selected').text().split(".")[0];

//Tricky Part : As this lead convert field mappings page doesn’t store Lead field API Names, it only contains lead field ID (15 digit SFDC ID) so we will have to do AJAX request of LEAD field detail webpage to fetch LEAD API Name corresponding to lead field ID
var contentText = $.ajax({url: "/" + this.name,async: false}).responseText;

//In fetched content, search and extract field API Name
var fromfield = $(contentText).find('td').filter(function () {
return $(this).text().indexOf('API Name') === 0;
}).closest('td').next().html();

//Similarly AJAX request for Account/Contact/Opportunity field detail page to fetch respective field API Name
contentText = $.ajax({url: "/" + this.value,async: false}).responseText;

//In fetched content, search and extract field API Name
var tofield = $(contentText).find('td').filter(function () {
return $(this).text().indexOf('API Name') === 0;
}).closest('td').next().html();

//Output LeadAPIName, Account/Contact/Opportunity APIName, Account or Contact or Opportunity
console.log(fromfield + ',' + tofield + ',' + objectname);

}});

Please Note:

  • This isn’t most neat and recommended way, so if you come across something really clean and less network consuming solution please share your solutions in comments below
  • I’m not an expert in jQuery, so there might be obvious and recommended ways of coding jQuery and my above coding might sound nascent way of handling jQuery, so please ignore my lack of knowledge around jQuery and help me to optimize same.
  • Fetching Lead/Account/.. Field API Name from Field ID might be done using other ways too (describe API Calls?), but thought of doing it in just one script, so did that using AJAX calls and parsing retrieved webpage content
  • As always, feedback/suggestions are always welcome

Auto-Refresh Salesforce Dashboard every 5, 10 or 15 … seconds, minutes or hours …

Is there a way we can have Salesforce Dashboard Auto-Refresh every few seconds (not recommended) or every x minutes or every x hours …?

Standard Out of box functionality does allow to refresh dashboard, but the lowest level of refresh interval is DAILY or WEEKLY or MONTHLY.

Lets say you want to have(display) a Sales Monitor always LIVE showing real time data, how do you achieve that?

There’s no direct way of doing it, but JS (as always) comes to the rescue …

  1. Log in to Computer (which is streaming output to LIVE monitor) , open Chrome browser (will try to update the script later to make it work in all browsers)
  2. Login to Salesforce and Navigate to desired Dashboard
  3. Delete url from  address/url bar, type (or copy+paste) below code and hit enter in address/url bar. (Make sure javascript: at start is there, chrome does remove it when copy pasted)

    javascript:function autorefresh() {document.getElementById('refreshButton').click();setTimeout(autorefresh, 5000);}autorefresh();

  4. Now do a full screen and enjoy Dashboard Live Monitor :)

 Please Note:

  1. 5000 represents 5000 milli seconds ie 5 seconds, so change the same according to your requirements ie if you want it to refresh every minute change the value to 60000
  2. This is not a recommended way, as its a tweak and might not work in future. (But as of now its working great and helps in having real time monitor of your favorite dashboard, so enjoy!)

Might be this can be an admin tool or a chrome extension, will try to make one when I get time and chance :)

Salesforce Data Storage – 2100 % Used – Whack!!!

Today I was doing data load (via some tool) and I was able to do data load of 420 MB, though my (or any) developer org allowed limit is 20 MB, Isn’t that strange!

I understand Salesforce does allow to store certain % beyond allowed limit, but this is almost 21 times allowed limit – sounds really whacky!

This is like hitting nail 21 times hard then allowed hit limit. Hope Salesforce Storage is not screaming :)

Chatter Stream or Chatter Ticker …

We have this amazing thing of collaboration inside Salesforce, the Chatter – an amalgamation of best features of Facebook and Twitter.  And to add, it’s for enterprise, so its Enterprise Collaboration Isn’t that awesome!!! Chatter supports lot of things post, comments, likes, follows etc and  best part is its not just user posts, comments etc .. its data posts, comments etc i.e., even the data is part of the collaboration . That adds to awesomeness!

However, there’s been one feature which I been waiting for and always wanted to see which is auto refresh of posts (for techies – ajax refresh) without need to refresh the entire page. Without this feature collaboration doesn’t seems to be complete and web2.0 type.  An alternative to auto refresh can be a stream or ticker (like we have Feed Ticker on facebook) which keeps scrolling and shows posts / comments happening around without need to refresh page.

So I thought of building the same, and first thing I needed was a poller which can poll and see if there are any chatter posts, but that would have been too resource intensive, and would have died after few hours because of governor limits and bla … bla … And to save me, there came a really great feature The Streaming API. I’m loving it!

Two lines about API - Use Streaming API to receive notifications for changes to Salesforce data that match a SOQL query you define in a secure and scalable way. Streaming API is useful when you want notifications to be pushed from the server to the client based on criteria that you define.

So what’s next, I was super excited to get all started to use Streaming API and poll Chatter objects.  I was able to get basic streaming API program working (after few discussions around streaming api with Pat Patterson, as the API had few issues in terms of documentation).

In basic example, I created a PushTopic (a SOQL query that you want notifications about) of Account. Now as the objective is chatter stream, so I tried to create a PushTopic around chatter object, and here was entry of the Villain – PushTopic aren’t supported yet for Chatter objects (SF please enable the same @ earliest)

So what next,  trigger the rescue man came to help. Developed few triggers which will do realtime snapshot of chatter objects, and then created push topic against these snapshot objects.  This way (though indirect way) I will be able to get push notifications (using streaming API)  of chatter posts…wow, finally I made it. I got the CHATTER STREAM or CHATTER TICKER ..

The use case of this is endless,  sky is not the limit..

ChatterTicker

Road map:

  • The notifications are lost the moment page is reloaded, so will try to add something which makes them persist until user has seen them.
  • Apply Sharing Settings, as currently all messages of  all users are shown

Trust me this idea struck me in morning and by evening the tool/app was ready. Thanks to Rajesh Shah for helping me out in testing this app.

 

Email to Chatter

How do I mass-move reports from one folder into another new folder

Problem Statement: We are currently cleaning up our report folders. In order to do so we want to move all unused reports into a ‘quarantene map’ before deleting them. How can we move a large number of reports all at once into one folder? i.e.,

Approach1
In the Eclipse IDE

  • Create a new project
  • Include ‘reports’ or more specifically the report folders you are concerned with
  • Let Eclipse refresh the project with the reports metadata
  • In Eclipse, navigate to the reports folder you just download and then select the Report Folder you want the reports you want to move from, right click and select Properties
  • Take Note of the Location. This is the path where the metadata files are located
  • Open a windows explorer window and navigate to that path
  • Highlight all the Reports you want to move and right click Cut
  • Still in the Window explorer navigate back to the list of report folder and expand the one you want to move the reports to and right click and Paste
  • Now back in the IDE highlight the folder titled Reports and right click and Refresh and then right click again and Force.com>Save to Server
  • BOOM! Now you have moved your reports.

 

Approach2

  • Another alternative would be to edit each report folder on the Report page and move unused reports to the Unfiled Public Reports folder.  You can then move all the reports in your Unfiled Public Reports folder to a new “quarantine” folder.  Yeah I know, still a lot of manual effort.

 

Approach3


Field datatype mapping between Oracle/SQL Server and Salesforce

Over the time I have started developing a tool that pulls salesforce metadata information and creates oracle/sql server “create table” scripts. Isn’t that really awesome!!

The most useful part of the tool is field data type mapping i.e, what data type of salesforce maps to what data type of oracle/sql server. Below is the list of mapping that I used while generating create table scripts – enjoy!!

salesforce data type sql server data type oracle data type
boolean bit varchar2(1)
date smalldatetime date
datetime Datetime date
currency decimal(precision,scale) number(precision,scale)
double decimal(precision,scale) number(precision,scale)
int Int number(10)
picklist nvarchar(255) varchar2(255)
id nvarchar(18) varchar2(18)
reference nvarchar(18) varchar2(18)
textarea nvarchar(max) varchar2(4000)
email nvarchar(255) varchar2(255)
phone nvarchar(255) varchar2(255)
url nvarchar(255) varchar2(255)
textarea nvarchar(max) varchar2(4000)
multipicklist nvarchar(max) varchar2(4000)
anyType nvarchar(max) varchar2(4000)
percent decimal(5,2) number(5,2)
combobox nvarchar(max) varchar2(4000)
base64 nvarchar(max) varchar2(4000)
time nvarchar(255) varchar2(255)
string nvarchar(length) varchar2(length)