Friday, December 28, 2012


Well few days ago while working with a Visualforce page I came across a requirement of showing currency field using proper currency formatting.


For Example

  • 6000 should appear as $6,000.00 in the vf page

After checking the standard Salesforce tags I was unable to find a solution. but somehow figured out that <apex:param> tag can be exploited here.

So do the currency formatting in a vf page you can use the below markup.

<apex:outputText value="${0, number, ###,###,###,##0.00}">  
      <apex:param value="{!Account.Amount__c}"/>  
 </apex:outputText>  

Hoping this helps for your currency formatting need!

Saturday, December 1, 2012


The Salesforce Winter 13 arrived with loads of new methods and upgrades.
From the long list of methods, Salesforce also  has provided a new method "getSObjectType()" for ID data type. This comes with lot relief as prior to API 26.0 there were no such method available by which we can get the sObject Type from Id of the sObject, instead we have to describe every object and match the prefix with the given sObject. A very resource hungry process.


 Map<String,Schema.SObjectType> gd = Schema.getGlobalDescribe();  
 Schema.DescribeSObjectResult r = gd.get(sObj).getDescribe();  
 String tempName = r.getName();  
 String tempPrefix = r.getKeyPrefix();  
 String ObjId= [SELECT Id FROM Account LIMIT 1];  
 String tPrefix = ObjId.subString(0,3);  
 //Get the Sobject Type  
 String objectType = keyPrefixMap.get(tPrefix);  
                                                                                                                            *above code is no longer needed



But with arrival of Winter 13 / 26.0 API you can directly get the Sobject Type By calling the "getSObjectType()" method.


/*IMPORTANT : replace "sObjId" with your sobject Id, you need not to query the record again,   
 just use the Id field from your record set/ record*/  
 Id sObjId = [SELECT Id FROM Account LIMIT 1].Id;  
 Schema.SObjectType token = sObjId.getSObjectType();  


This new method will be really helpful in writing dynamic apex code for triggers and batches and even for visualforce controllers.


Monday, November 12, 2012


Well someday back, while writing a Visualforce page I came across a situation where I have to convert a string to Id. I tried to check methods for "Id" but couldn't find any thing well after lot tries I actually figured out a way to convert "string" to "Id".

It is super easy, you just need to follow the following code :


 String strId = 'a08A000000ZdZYk';  
 Id myId = strId;  


Hope this helps.

Wednesday, November 7, 2012


[Live Demo]



Please Note : A Newer Version of this Package is available here http://blogforce9.blogspot.in/2013/10/auto-complete-visualforce-component-v2.html


Well working with visualforce pages, I was always tempted to replace the boring lookup field with a autocomplete component which searches the records as we enter text in them. 

So I sat done and wrote a component for my visualforce pages to replace the boring lookup fields dialogs with autocomplete component.


Few features of the autocomplete component
  • Uses Jquery UI to create the autocomplete component.
  • Look And Feel - Has exactly same look and feel as native components
  • Uses Js Remoting to populate data and hence the component is very fast and light weight.
  • Configurable : The search field can be configured to search fields other than "Name" field. Even the value that is returned to controller can be configured return fields other than record Id.
How to use the component in you Visualforce page?


<c:Autocomplete labelField="Name" valueField="Id" SObject="Contact" targetField="{!targetFieldCon}" /> 

Description
  • labelField : The field which is displayed in the component  and against which matching is done with the entered text. In above code snippet Name is displayed in the autocomplete component.
  • valueField : The field value which is passed back to targetfield when a record is selected.
  • targetField : The field from controller where the selected values is set.
  • SObject : The sobject Api Name against which matching/query is done.
For demo purpose you can check the "autocomplete" vf page that is included in package. This page demonstrates the use of the autocomplete component for different sObjects.

Screen : 




Please Note : A Newer Version of this Package is available here http://blogforce9.blogspot.in/2013/10/auto-complete-visualforce-component-v2.html
Package Link :http://blogforce9dev-developer-edition.ap1.force.com/ProjectDetail?id=a0290000007rf2z

Monday, October 15, 2012



As Salesforce is becoming more and more advanced with every release we developer are trying to cope up with the new features released.
Salesforce are releasing awesome features with every release. One of the most remarkable feature is fieldsets.

Fieldsets takes away the most annoying problem of visualforce pages i.e. it makes the pages dynamic!!. Yes Dynamic. The let of configure the fields that
appear in your visualforce page.

How to use fieldsets in your visualforce page.??

<apex:page controller="AccountCon">  
   <apex:form>  
     <apex:pageblock>  
       <apex:pageblocksection columns="1">  
         <apex:repeat value="{!$ObjectType.Account.FieldSets.AccountFieldSet}" var="f">  
             <apex:inputfield value="{!accObj[f]}">  
         </apex:inputfield>  
       </apex:repeat>  
     </apex:pageblocksection>  
   </apex:pageblock>  
  </apex:form>  
 </apex:page>  

public class AccountCon(){  
  public Account accObj{get;set;}  
  public AccountCon(){  
  accObj = [SELECT id,Name FROM Account LIMIT 1];  
  }  
 }  


Well easy enough?
But there lies a problem with fieldsets. In the above example you can see that a static query brings out data from salesforce objects. It will work
just perfect, until and unless some new field that is not included in query is introduced in the query. Once such field is included the code will throw an
exception.

Solution??
Make your query as dynamic as fieldsets!!
To do this I have devised a util class that dynamically generates query using fieldset/fieldsets. Just pass the object name and fieldset name this
will generate a dynamic query according to the parameters passed. Use the returned string to query the data.

Show Me The Code!!
Below is the util class that can be used to generate dynamic query from fieldsets.


 /*  
 *This Class contains utility methods that are used by different classes  
 *in the Org  
 **/  
 public class AVCommonUtils{  
   Map<String, Schema.SObjectType> globalDescribe;   
   public AvCommonUtils(){  
     globalDescribe=Schema.getGlobalDescribe();  
   }  
   /*This method return queries form a single fieldset  
   public String generateQueryFromFieldSet(String sObjectName,String fieldSet,Set<String> additionalFields,String whereClause){  
     return generateQueryFromFieldSets(sObjectName,new Set<String>{fieldSet},additionalFields,whereClause);   
   }  
   /*  
   *This method generates query according to passed in object and fieldsets(plural) name  
   **/  
   public String generateQueryFromFieldSets(String sObjectName,Set<String> fieldSets,Set<String> additionalFields,String whereClause){  
     Set<String> fields = new Set<String>{'Id'};  
     String query='SELECT Id';  //initial query  
     if(additionalFields!=null)  
     for( String fs : additionalFields ) {            
       //add only unique fields  
       if(!fields.contains(fs)){  
         //maintain a set of fields so that only unique fields are added in query  
         fields.add(fs);  
         query = query+','+fs;  
       }      
     }  
     //describe the provided sObject  
     Schema.DescribeSObjectResult res=globalDescribe.get(sObjectName).getDescribe();  
     //get the fields set map  
     Map<String, Schema.FieldSet> fieldSetMap= res.fieldSets.getMap();  
     //iterate through provided fieldsets and generate query  
     for(String fieldSetName : fieldSets){  
       Schema.FieldSet fs = fieldSetMap.get(fieldSetName);  
       for( Schema.FieldSetMember fsm : fs.getFields() ) {            
         //add only unique fields  
         if(!fields.contains(fsm.getFieldPath())){  
           //maintain a set of fields so that only unique fields are added in query  
           fields.add(fsm.getFieldPath());  
           query = query+','+fsm.getFieldPath();  
         }      
       }  
     }  
     query = (whereClause == '' || whereClause ==null)   
             ? (query + ' FROM '+sObjectName)   
             : (query + ' FROM '+sObjectName + ' WHERE ' + whereClause);  
     return query;  
   }  
 }  


How to use the util class??
Let us rewrite the above controller "AccountCon" using the util class.

 public class AccountCon(){   
  public Account accObj{get;set;}   
  public AccountCon(){   
      AVCommonUtils util = new AVCommonUtils();  
      String query = util.generateQueryFromFieldSet('Account','AccountFieldSet',null,'LIMIT 1');  
       accObj = database.query(query);    
  }   
  }   


Well the util classs has two methods.

  1. generateQueryFromFieldSet : This method generates query from only one fieldset
  2. generateQueryFromFieldSets: This method takes in a set of fieldset name to generate query.



Monday, September 10, 2012




In Earlier post "Using Variables In Dynamic SOQL",  I wrote about how to use variables in a Dynamic SOQL. Well after playing with Dynamic SOQL, I found few interesting thing like:

·         You CAN directly use primitive data types in SOQL.

So what does this means?
This means you can directly use any Integer, String , Date, Datetime,Double, Id variable along with Collection of this variable within the query.

For Example: 

a) You are allowed to do this
//initialize the Datetime with current time
DateTime now = System.now();
//query accounts by merging the variable name inside the query string
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE CreatedDate =:now');

b)You can also include LISTs(Collections) in your queries
List<String> accNameList = new List<String>{'Acc1','Acc2'}
//query accounts by merging the variable name inside the query string
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE Name IN:accNameList');


·         You CANNOT use complex types in a Dynamic SOQL directly.
This means that you cannot use any Sobject, Apex Class or Any other user defined data type inside the Dynamic Query. In short you cannot use a dot (".") operator to specify a field value in a Dynamic query.

For Example :

                a)  Using an Sobject inside the query String will not work
           //initialize a Account with a Name value for demo
Account acc = new Account(Name='MyAccount');
//query accounts by merging the variable name inside the query string
//This will not work
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE Name =:acc.Name');

//But You can always make the above work by writing the code as.

           //initialize a Account with a Name value for demo
      Account acc = new Account(Name='MyAccount');
      String accountName = acc.Name
      //query accounts by merging the variable name inside the query string
      List<Account> accountList = Database.query('SELECT Id FROM Account WHERE                       
      Name =: accountName  ');


Hope this helps!.





Saturday, September 8, 2012



10-Sep-2013 : Have a look at my MapMyObject Component, A very flexible Google Map Mapping component.

This is one of the most frequently asked question "How to integrate Salesforce with Google Maps?"
What if you want to show the address of a Say "Account" in the account detail page?
Well the solution is create a inline visualforce page for account and call the google geocoding service to geocode the address ,use that location to mark a point on the map.

Sounds difficult right?
Well in reality its very easy. Just some fancy Java script calls and its done.
Just see the below visualforce page which pulls the Billing Address from the account and displays the same, this page can be included in the Account detail page layout.

Features

  • Shows the Billing Address of the Account in the map
  • On click of the marker a info window is shown with the formatted address.

 <apex:page standardController="Account">  
   <!-- Import Necessary Jquery js File and StyleSheets-->  
   <apex:includeScript value="https://maps.googleapis.com/maps/api/js?sensor=false"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-1.6.2.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-ui-1.8.16.custom.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jqPlugin, '/jquery.blockUI.js')}"/>  
   <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'css/ui-lightness/jquery-ui-1.8.16.custom.css')}"/>  
   <script>  
      var map,geocoder,infowindow;  
      var latLngs = [];  
      $j = jQuery.noConflict();   
      $j(document).ready(function(){  
        initialize();  
      });  
      function initialize() {  
       geocoder = new google.maps.Geocoder();  
       //initial cordinates for map init  
       var latlng = new google.maps.LatLng(37.09024, -95.712891);  
       var myOptions = {  
         zoom: 4,  
         center: latlng,  
         mapTypeId: google.maps.MapTypeId.ROADMAP  
       };  
       //load the map  
       map = new google.maps.Map($j('#map')[0], myOptions);  
       codeAddress();  
      }  
      /*This function codes the address using the Billing Address in the Acoount*/  
      function codeAddress(){  
        //prepare a string for geocoding  
        var address = '{!Account.BillingStreet},{!Account.BillingCity},{!Account.BillingCountry},{!Account.BillingPostalCode}';  
        console.log(address);  
        //geocode the address  
        geocoder.geocode( { 'address': address }, function(results, status) {  
          //if it is a success  
          if (status == google.maps.GeocoderStatus.OK) {  
            var location = results[0].geometry.location;  
            var marker=addMarker(location );  
            //attach info window to the marker  
            attachInfoWindow(marker,results[0]);  
          }  
          else {  
            alert(status);  
          }  
        });   
      }  
      /*  
      *This method adds a marker to the provided location  
      **/  
      function addMarker(location) {  
       marker = new google.maps.Marker({  
           position: location,  
           map: map  
         });  
         //set the bounds and initial zoom  
       var latlngbounds = new google.maps.LatLngBounds();  
       latlngbounds.extend(marker.getPosition());  
       map.fitBounds(latlngbounds);  
       map.setZoom(14);  
       return marker;  
      }  
     //this function shows the address of a marker when it is clicked  
     function attachInfoWindow(marker,address){  
        google.maps.event.addListener(marker, 'click', function() {  
          if(infowindow!=null)  
           {  
             infowindow.close();  
           }  
         //HTML formated string that is used to dispaly info window over the map markers currently showing the formated address  
         var contentString = '<div class=" ui-state-active ui-corner-top" style="font-size: 1em; padding: 5px;">Address</div>'  
                   +'<div class="ui-widget-content ui-corner-bottom" style="font-size: .9em; padding: 15px;">'+address.formatted_address+'</div>';  
         infowindow = new google.maps.InfoWindow({  
           content: contentString  
         });  
          infowindow.open(map,marker);  
        });  
     }  
   </script>  
   <style>  
     #map {  
       width:100%;  
       height:200px;   
       margin-left:1.5%;  
     }  
   </style>  
   <div id="map" class="ui-widget-content ui-corner-all ui-state-default"></div>  
 </apex:page>  


How the page looks like?


Page showing the Location of Account


The info window showing the address

Package/Installation
You can use this package to install the same in your org 
https://login.salesforce.com/packaging/installPackage.apexp?p0=04t90000000M5aT
The above package contains a page called LocateAccount that can be used inline in the Account detail page to display the location or you can pass the Id of account to the page like this /apex/LocateAccount?id=<ACCOUNT ID>".