As we know that when want to autopopulate a custom field on
standard insertion page from a custom button we do url hacking with custom field
id. But custom field id is different from one org to other org. So when we
deploy the custom button then again we have to replace the custom field id from
the destination org. That means we have to change custom field ids whenever we
deploy custom button from one org to another org manually.
If we do the same thing dynamically we don't need to worry
about replace of custom field id after deployment.
For getting custom field id dynamically from a specificic
custom field on an object we can use
"Tooling API". We have an
object "CustomField" to get the custom field information from "Tooling
API".We can get 18 characters id of custom field. But for populating
customfield salesforce expects only 15 characters so after getting the id of
custom field from tooling api we have to make it from 18 characters to 15
characters.
Tooling Api supports Rest API. So we can get the custom
field id by using http callouts as shown below.
HttpRequest req = new HttpRequest();
req.setHeader('Authorization','Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type','application/json');
req.setEndpoint(toolingapiurl);
req.setMethod('GET');
// Send the request, and return a response
HttpResponse res = h.send(req);
For example i have "languages__c" custom field on contact
object. I want to populate it with a value "English" from custom
button "Create Contact" on Account record detail page as shown below.
Account Detail Page
Custom button code as shown below:
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")}
var result =
sforce.apex.execute("RetrieveCustomFieldIdCls","getCustomFieldID",{customFieldName:"Languages__c",objectName:"Contact"});
window.open('/003/e?retURL=%2F{!Account.Id}&accid={!Account.Id}&'+result+'=English','_self');
in the above code "result" variable gets the custom field id from a
method "getCustomFieldId" referenced in the
"sforce.apex.execute" method.
here we are passing two parameters "Custom Field
Name","Object Name".
I am passing " Languages__c"," Contact".When
we click on custom button "Create Contact" it retrieves the
"Languages__c" custom field id and then preparing url in the next
line as shown below.
window.open('/003/e?retURL=%2F{!Account.Id}&accid={!Account.Id}&'+result+'=English','_self');
Here "result" variable contains custom field id.
Now we don't need to replaces the custom field id after
deployment.Becase we are dynamically getting the customfield id from Tooling
API.
Class for custom button to retrieve custom field
Id:
global class RetrieveCustomFieldIdCls {
webservice static
string getCustomFieldID(String customFieldName,String objectName){
String
customFieldId='';
String
customField=customFieldName.removeEndIgnoreCase('__c');
Http h = new
Http();
//
Instantiate a new HTTP request, specify the method (GET) as well as the
endpoint
HttpRequest
req = new HttpRequest();
req.setHeader('Authorization','Bearer ' +
UserInfo.getSessionID());
req.setHeader('Content-Type','application/json');
String
fullFileURL = URL.getSalesforceBaseUrl().toExternalForm();
String
url1=fullFileURL+'/services/data/v28.0/tooling/query/?q=Select+id,+DeveloperName+from+customField+Where+DeveloperName=\''
+ customField + '\'+and+TableEnumOrId=\''+objectName+'\'';
req.setEndpoint(url1);
req.setMethod('GET');
// Send the
request, and return a response
HttpResponse
res = h.send(req);
RetrieveFieldParsercls retrieveObj=(RetrieveFieldParsercls)
System.JSON.deserialize(res.getBody(), RetrieveFieldParsercls.class);
System.debug('##:'+retrieveObj);
for(RetrieveFieldParsercls.retrieveFieldDetails
retrieveFieldDetailObj:retrieveObj.records){
customFieldId=String.valueOf(retrieveFieldDetailObj.Id).substring(0,15);
}
return
customFieldId;
}
}
JSON parser class:
public class RetrieveFieldParsercls{
public Integer size; //1
public Integer totalSize; //1
public boolean done;
public cls_queryLocator queryLocator;
public String entityTypeName; //CustomFieldDefinition
public retrieveFieldDetails[] records;
public class cls_queryLocator {
}
public class retrieveFieldDetails {
public cls_attributes attributes;
public String Id; //00N280000025vdlEAA
public String DeveloperName; //Active
}
public class cls_attributes {
public String type; //CustomField
public String url; ///services/data/v28.0/tooling/sobjects/CustomField/00N280000025vdlEAA
}
}
JSON parser class:
public class RetrieveFieldParsercls{
public Integer size; //1
public Integer totalSize; //1
public boolean done;
public cls_queryLocator queryLocator;
public String entityTypeName; //CustomFieldDefinition
public retrieveFieldDetails[] records;
public class cls_queryLocator {
}
public class retrieveFieldDetails {
public cls_attributes attributes;
public String Id; //00N280000025vdlEAA
public String DeveloperName; //Active
}
public class cls_attributes {
public String type; //CustomField
public String url; ///services/data/v28.0/tooling/sobjects/CustomField/00N280000025vdlEAA
}
}
Note:-we are doing
http callout so we have to set endpoint url in Remote Site Settings accordingly.
Contact Screen when we click on "Create Contact"
button on account record detail page