Tuesday, March 4, 2014

Salesforce URL Hacking to Prepopulate Fields on a Standard Page Layout using Tooling API

To build Salesforce URL’s to standard pages for creating records, that can be applied to Custom Buttons in order to pre-populate field values when a user clicks a button native using Tooling API.

Tooling API support for Custom Object and Custom Fields

This can query (REST or SOAP) the CustomObject and CustomField objects (which are not accessible via Apex SOQL).As we know every object in Salesforce has an ID and thia API has the means to obtain the custom field Id’s.

We have  Apex wrapper for the Tooling API which can referred here

I tried to use the REST and getting a CustomObject's CustomFields Ids by using the below approach..

This code is just my work according to my requirement and can be extended up to your requirements..

NOTE: This supports only for CustomObjects and CustomFields.

To test this send the object name to the below method.

FieldIdUtil.findFieldIds('CustomObjectName') //Don't Append '"__c" for example
FieldIdUtil.findFieldIds('Implementation') //Don't Append '"__c"
You should give the object name but not the API name

This method will return map of custom fields with the respective field IDs from which we can grab the fields what ever we want to pre-populate

1. Consider the objectname is 'Implementation' and the fields in this are  'Field1', 'Field2';



1:  public class FieldIdUtil   
2:  {  
3:       public Static Map<String,String> fieldIdsMap = new Map<String,String>();  
4:       public Static String objectId; 
         
         public static List CustomApexTypes = new List();
 
 public class CustomApexType
        {
           public String Id;
           public String DeveloperName;
        }

5:       public static Map<String,String> findFieldIds(String ObjectName)   
6:    {  
7:         String objectIdQuery = 'Select Id From CustomObject Where DeveloperName = \''+ObjectName+'\'';  
8:      sendCallout(objectIdQuery, true);  
9:      if(objectId != null)  
10:      {  
11:        String fieldIdsQuery = 'Select Id, DeveloperName From CustomField Where TableEnumOrId = \''+objectId+'\'';  
12:        sendCallout(fieldIdsQuery, false);  
13:      }  
14:         return fieldIdsMap;  
15:       }  
16:       private static void sendCallout(String query, boolean flag)  
17:       {  
18:            String strIdValue,devName;  
19:            HttpRequest req = new HttpRequest();  
20:      req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());  
21:      req.setHeader('Content-Type', 'application/json');  
22:      String environmentURL =   
23:          URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v28.0/tooling/query/?q=' + EncodingUtil.urlEncode(query, 'UTF-8');  
24:      req.setEndpoint(environmentURL);  
25:      req.setMethod('GET');  
26:      Http h = new Http();  
27:      HttpResponse res = h.send(req);  
28:      JSONParser parser = JSON.createParser(res.getBody());  
29:      while (parser.nextToken() != null)
  {
      if ((parser.getText() == 'records'))
      {
          parser.nextToken();
  
          CustomApexTypes = (List<CustomApexType>)parser.readValueAs(List<CustomApexType>.class);
      }
  }  
64:   }  
65:  }  

The below code will generate the URL and the parameters from the above methods and do the redirect to a standard page by auto populate the specified values


1:  public PageReference doredirect()  
2:    {  
3:         Map<String,String> fieldIdsMap = new Map<String,String>();  
4:          Set<String> fieldAPINames = new Set<String>  
5:        {'Field1','Field2'};  
8:         fieldIdsMap = FieldIdUtil.findFieldIds('Implementation');//Passing the custom object name  
9:         PageReference pr = new PageReference(URL.getSalesforceBaseUrl().toExternalForm() + '/' + Implementation__c.SObjectType.getDescribe().getKeyPrefix() + '/e');  
10:         Map<String, String> params = pr.getParameters();  
           //we will be able to get the Master or Lookup id like this '00N11000000GysA' but inorder to refer in page we should add "CF"
            to the ID"
11:         //params.put('CF00N11000000GysA', Opp.Name);  // if you have parent object like opportunity we need to do this bit
12:      //params.put('CF00N11000000GysA' + '_lkid', Opp.Id);  // if you have parent object like opportunity we need to do this bit

13:         for(String fieldAPIName : fieldAPINames)  
14:         {  
15:           params.put(fieldIdsMap.get(fieldAPIName), (String) Opp.get(fieldAPIName));  
16:            }  
17:         params.put('saveURL',opp.id);  
18:      params.put('retURL', opp.id);  
19:         pr.setRedirect(true);   
20:         system.debug('*************' + pr);  
21:         return pr;  
22:    }  

This is just my initial thoughts and worked solution for me ..There may be some changes and best practices you may found to change in this code....

here is my experience in making this solution before taking to Production.  

No comments:

Post a Comment