PS This hack is broken in Summer ’15; the class name “requiredMark” looks like it has changed to “assistiveText”.
I was asked in a comment on Hack to find field ids – allows a default UI “New” page to be pre-populated to post the code so I have done so below. Remember this is a hack.
Before using this code, consider instead using the more recent Tooling API – see Andrew Fawcett’s Querying Custom Object and Field IDs via Tooling API.
public class LkidUtil { /** * This field id is needed to pass parameters to default UI. Unfortunately there is no API to obtain it, hence this hack. * Takes about 50-100ms. Results could be cached in a custom setting if that became problematic. */ public static String findFieldId(SObjectType sobType, SObjectField field) { return findFieldIds(sobType, new SObjectField[] { field })[0]; } public static String[] findFieldIds(SObjectType sobType, SObjectField[] fields) { // Crazy but necessary: parse default UI HTML for required id PageReference p = new PageReference('/' + sobType.getDescribe().getKeyPrefix() + '/e?nooverride=1'); String html = p.getContent().toString(); List ids = new List(); for (SObjectField field : fields) { DescribeFieldResult f = field.getDescribe(); String label = f.getLabel(); ids.add(matchFieldId(html, label)); } return ids; } // Public for testing public static String matchFieldId(String html, String label) { // Non-greedy ? wasn't sufficient; now limit the matching characters to "word character", usually [A-Za-z0-9_], which is ok for the field id Matcher m = Pattern.compile('(<span class="requiredMark">\\*</span>)?' + label + '').matcher(html); // Use first match if (m.find()) { return m.group(1); } else { return null; } } }
Note calls to this need guarding for tests to work:
String[] fieldIds; if (!Test.isRunningTest()) { // Contains code that causes tests to (silently) abort fieldIds = LkidUtil.findFieldIds(Document__c.SObjectType, new SObjectField[] { Document__c.Claim__c, Document__c.BenefitClaimed__c, Document__c.Type__c }); } else { // Used in test fieldIds = new String[] { 'FakeClaimFieldId', 'FakeBenefitClaimedFieldId', 'FakeTypeFieldId' }; }
And here is a unit test (limited by the fact that the page HTML cannot be generated in a test):
@isTest private class LkidUtilTest { @isTest static void testRegexPatternRequiredField() { // Always worked doTestRegexPattern('<td class="labelCol requiredInput"><label for="00NK0000000ap5l"><span class="requiredMark">*</span>Type</label></td>'); // Was broken doTestRegexPattern('<label for="Name"><span class="requiredMark">*</span>Document Name</label></td><td class="dataCol col02"><div class="requiredInput"><div class="requiredBlock"></div><input id="Name" maxlength="80" name="Name" size="20" tabindex="1" type="text" /></div></td><td class="labelCol requiredInput"><label for="00NK0000000ap5l"><span class="requiredMark">*</span>Type</label>'); } @isTest static void testRegexPatternNonRequiredField() { // Always worked doTestRegexPattern('<td class="labelCol"><label for="00NK0000000ap5l">Type</label></td>'); // Was broken doTestRegexPattern('<label for="Name"><span class="requiredMark">*</span>Document Name</label></td><td class="dataCol col02"><div class="requiredInput"><div class="requiredBlock"></div><input id="Name" maxlength="80" name="Name" size="20" tabindex="1" type="text" /></div></td><td class="labelCol"><label for="00NK0000000ap5l">Type</label>'); } private static void doTestRegexPattern(String html) { System.assertEquals('00NK0000000ap5l', LkidUtil.matchFieldId(html, 'Type')); } }