[SalesForce] Set default value on children records when `New` is clicked on related list

One of the custom objects I have is rendered as a Related List of Opportunity. This custom object also has a custom field of Opportunity lookup type. To create a record of this type I go to Opportunity -> Related List and click on New button.

What I want is : At the time of record creation I want to assign default values to certain fields. The way it should work is Mailing Address field should get its value from related Opportunity's primary Contact. I can achieve this in a trigger by executing a query like

SELECT MailingAddress 
  from CONTACT 
  WHERE id IN (SELECT contactID 
                FROM OpportunityContactRole 
                WHERE opportunityID = <variable> and isPrimary = true)

However, I want to do it by assigning a formula to the default value to Mailing Address filed directly. Is it possible?

Second part of this question is… While trying to set the default value for this custom field I tried something like Opportunity__c.Mailing_Address__c (This is a custom field on Opportunity), however the formula validation error I got was

Error: Field Opportunity__c does not exist. Check Spelling. Opportunity__c in fact exists as a lookup Opportunity Field in my custom object.

Any pointers are greatly appreciated.

Thanks

Best Answer

A default value will not work in this case, because default values can't access values on a parent record. They are set at the schema level, and don't have the context of where the record is created (e.g. from which parent object).

Overriding the New action with a Visualforce page would work, but is not entirely optimal because this also overrides New everywhere it appears (not just on the custom object related list on the opportunity page layout). You would have to write logic in your controller to check which context New is being called in.

You could create a custom URL button that uses URLFOR() to call a Visualforce page, and only use it on the Opportunity page layout. You would then pass in the parent opportunity ID as a parameter to the VF page. The controller would then have to get the parameter and use it to set the field value in the VF page. (This is not the same as URL hacking, in which the field identifier is added to the query string and passed into the standard page layout. URL hacking is unsupported and will break as Salesforce moves toward Aura/Lightning for desktop pages.)

Another option, if you have Publisher Actions enabled in Chatter, is to create an object-specific quick action on the Opportunity object to create the custom object, and add it to the Chatter publisher. Effective Spring '15 you can span multiple levels of objects in predefined values, which would allow you to reach the Contact object on the Opportunity. You can't access the MailingAddress field directly (since it's an Address field type) but you can concatenate the MailingStreet, MailingCity and MailingState in the formula, which would look something like (for a TextArea):

Opportunity.Contact__r.MailingStreet & BR() 
& Opportunity.Contact__r.MailingCity & ", " & Opportunity.Contact__r.MailingState

The result would be something like this: enter image description here

The advantage to this method is (1) it's supported, (2) it doesn't require any Apex, and (3) it works in Salesforce1 (custom URL buttons aren't supported in S1 yet). The disadvantage is that you have to train users to use the quick action instead of the New button on the related list, but you could hide the New button on the related list to enforce that.