Pre-populating Standard Page Layouts

Warning: This uses undocumented methods. As with any code that relies on anything undocumented it’s not supported and it’s prone to breaking without warning so don’t rely on it working tomorrow!

It’s a known hidden feature of Salesforce that you can pre-populate fields on a standard page layout if you know the name of the fields. There are plenty of blogs on it. For example you can pre-populate the Account Name with the URL:

https://na43.salesforce.com/001/e?acc2=Peace+Without+Walls+Inc&acc5=012345

screenshot-2017-02-28-21-51-44

This gets a bit trickier still on custom page layouts:

https://na43.salesforce.com/a0Q/e?Name=Red%20Widget&00N0G00000DaxKQ=RED

screenshot-2017-02-28-21-53-45

Yeuck! Where did 00N0G00000DaxKQ come from? You have to dig it out using your browser developer tools.

Another blog post on the matter …

So to make this a bit easier, we’re going to write a little VF page and Controller to fathom it all out for us. We’ll only need to remember nice things like Developer Names for stuff.

To do this we need to query two system objects, the EntityDefinition and the FieldDefinition.

The Entity Definition will give us the URL and its Id as contained in the DurableId field.

Select DeveloperName, DurableId, EditUrl, NewUrl From EntityDefinition Where DeveloperName = 'Widget'

DeveloperName: Widget
DurableId: 01I0G000002e6SD
EditUrl: /{ID}/e
NewUrl: /a0Q/e

Using the DurableId from the first Query we can get the Field Definitions:

Select DeveloperName, DurableId, EntityDefinitionId, RunningUserFieldAccessId From FieldDefinition Where EntityDefinitionId = '01I0G000002e6SD' and DeveloperName = 'Colour'

DeveloperName: Colour
DurableId: 01I0G000002e6SD.00N0G00000DaxKQ
EntityDefinitionId: 01I0G000002e6SD

By stripping away everything after and including the . on the DurableId we are left with the Field Id we need to use in our URL.

So lets build something a bit more usable …

Controller:

public without sharing class PreloadPageLayoutController
{
	public String RedirectURL {get; set;}

	private static final String OBJECT_PARAMETER_KEY = 'o';

	/**
	 * Constructor - Builds URL
	 */
	public PreloadPageLayoutController()
	{
		// Page Parameter Map
		Map paramMap = ApexPages.currentPage().getParameters();

		// Get the Object Parameter
		String objectName = paramMap.get(OBJECT_PARAMETER_KEY);

		// Map the Key Pairs
		Map fieldMappings = new Map();
		fieldMappings.putAll(paramMap);
		fieldMappings.remove(OBJECT_PARAMETER_KEY);

		try
		{
			// Query the Entity Definition for the Object
			EntityDefinition ed = [Select DeveloperName, DurableId, EditUrl, NewUrl
									From EntityDefinition
									Where DeveloperName = :objectName];

			Map fieldNameToIdMap = new Map();

			Set fieldNames = fieldMappings.keySet();

			// Query the Field Definition for the Fields and Map the Developer Names to the Field Ids
			for (FieldDefinition fd : [Select DeveloperName, DurableId, EntityDefinitionId
										From FieldDefinition
										Where EntityDefinitionId = :ed.DurableId and
											DeveloperName in :fieldNames])
			{
				String[] idParts = fd.DurableId.split('\\.');

				fieldNameToIdMap.put(fd.DeveloperName, idParts[1]);
			}

			// Build the URL
			RedirectURL = ed.NewUrl;

			String prefix = '?';

			// Loop through the parameters
			for (String key : fieldMappings.keySet())
			{
				String value = fieldMappings.get(key);
				String fieldId = fieldNameToIdMap.get(key);

				String paramTemplate = '{0}{1}={2}';
				String param = String.format(paramTemplate, new String[] { prefix, fieldId == null ? key : fieldId, value });
				RedirectURL += param;

				prefix = '&';
			}

			ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Redirecting to: ' + RedirectURL));
		}
		catch(Exception e)
		{
			ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage() + ' ' + e.getStackTraceString()));
			RedirectURL = null;
		}
	}

	/**
	 * Action Method to Redirect
	 */
	public PageReference redirect()
	{
		PageReference ref;

		if (RedirectURL != null)
		{
			ref = new PageReference(RedirectURL);
			ref.setRedirect(true);
		}

		return ref;
	}
}

Quick Unit Test Class:

@isTest
private class PreloadPageLayoutControllerTest {

	@isTest static void testParams()
	{
		Map paramMap = ApexPages.currentPage().getParameters();
 		paramMap.put('o', 'Account');
 		paramMap.put('Name', 'Test');
 		paramMap.put('acc2', 'Test2');

		PreloadPageLayoutController controller = new PreloadPageLayoutController();
		PageReference ref = controller.redirect();
		Map newParamMap = ref.getParameters();
		System.assert(newParamMap.containsKey('Name'));
		System.assertEquals('Test', newParamMap.get('Name'));
		System.assert(newParamMap.containsKey('acc2'));
		System.assertEquals('Test2', newParamMap.get('acc2'));
	}
}

Visualforce Page: PreloadPageLayout:


		If your page does not redirect automatically click here

We can now pass the parameters to our custom page instead but instead of having to inspect the page and work out the yeuky ids we can use the Developer Names instead:

https://na43.salesforce.com/apex/PreloadPageLayout?o=Widget&Name=Red+Widget&Colour=RED

It also works on Standard Objects for Custom fields only. For Standard fields you still need to use acc1, acc2, acc3 etc:

https://na43.salesforce.com/apex/PreloadPageLayout?o=Account&acc2=Peace+Without+Walls+Inc&acc5=012345&My_Rating=Good

You can also use it from your own Apex Code to do a redirect and pre-load the page:

public PageReference redirect()
{
	PageReference ref = Page.PreloadPageLayout;
	ref.getParameters().put('o', 'Widget');
	ref.getParameters().put('Name', 'Red Widget');
	ref.getParameters().put('Colour', 'RED');

	return ref;
}

Another use is a Custom Button to Add Red Widgets:

screenshot-2017-03-01-19-18-29

which you can then add onto the Search Layout.

Advertisements

Author, brainstormer, coder, dad, explorer, four chord trickster, gig goer, home worker, inquisitor, joker, knowledge seeker, likes: marmite, note scribbler, opinionator, poet, quite likes converse, roller skater, six music listener, tea drinker, urban dweller, vinyl spinner, word wrangler, x-factor hater, Yorkshireman (honorary), zombie slayer (lie).

Tagged with: , , ,
Posted in apex, code, force.com, salesforce
One comment on “Pre-populating Standard Page Layouts
  1. Ash Arnett says:

    Totally Awesome post.

Comments are closed.

About Me
Product Services Developer at:
FinancialForce.com
All views expressed here are my own. More about me and contact details here.

Enter your email address to follow this blog and receive notifications of new posts by email.

Copyright (there isn’t any, feel free to reuse!)

CC0
To the extent possible under law, Tony Scott has waived all copyright and related or neighboring rights to MeltedWires.com Examples and Code Samples. This work is published from: United Kingdom.

%d bloggers like this: