Create a Custom ‘New’ Button on a Related List to Return to the Parent Record After Clicking Save

IMPORTANT NOTE

Be aware that the “URL Hacks” that we had been using in Salesforce Classic are not guaranteed to work in Lightning Experience because of a change in the way the UI constructs and handles URLs.

If you would like to implement a similar solution that will work in Lightning Experience, I recommend using a either a Visualforce Page with a Custom Button on the Detail Page or Related List to perform this function, a Quick Action or a custom Lightning Component.

I will be replacing this page with an updated method for performing the function described below, so please consider the risks before implementing this solution.

Use Case

In Salesforce, when you click on the standard ‘New’ button on a Related List to create a new record on the child object from the record currently in context in a Detail Page, after you click ‘Save’ and save the new record, it returns you to the Detail Page for the newly created record by default. For parent-child object relationships that have high levels of data entry on the child object, this creates a user experience issue as the user will have to click on the link to the parent record in order to return to the Detail Page to continue adding child records or perform additional functions on the parent record.

Solution

The concept behind the solution is straightforward enough, but there are some tricky potential “gotchas” in the implementation that we need to be mindful of. What we are going to do is create a new Custom Button on the child / target object to replace the standard ‘New’ button that gets displayed on a Related List when looking at the Detail Page of a parent record.

The first thing that we need to do is grab the ID of the Lookup field on the child object that represents either the Lookup or Master-Detail Relationship to the parent object. This is important, because we will need to include two URL parameters that provide the record ID of the parent record, otherwise the lookup field will have a blank value when we create a new child record using this new custom button; this would require the user to manually perform a lookup, which is self-defeating since the expected behavior when clicking a ‘New’ button on a related list is to have the parent record ID available in context to pre-populate the dependent field.

To do this, simply go to the Detail Page for a record on the parent object. Navigate to the related list for the child object (obviously you would need to add this if it didn’t already exist), and click the ‘New’ button.  Copy the URL of the new page that appears and paste it somewhere that can be referenced throughout this process. It should look something like this:

https://naX.salesforce.com/a00/e? CF00NE0000002UJYd=Name+of+Parent+Record &CF00NE0000002UJYd_lkid=a03E0000002255P &retURL=%2Fa03E0000002255P

Whoa! What does all of this mean?

  • naX.salesforce.com – This is the instance of Salesforce that you are currently working on.  An example could be ‘NA9′.
  • a00 – This is the ID of the object that we are creating a new record for.
  • e? – This simply means that we are editing a record.  Now the ‘?’ character is the important part – this means that there are some parameters being passed through in the URL, and that whatever follows the ‘?’ is a parameter, which in this case is…
  • CF00NE0000002UJYd=Name+of+Parent+Record – This just happens to be the first parameter that was appended to this URL…do not worry about the order in which parameters appear in the URL. But when we see something with the prefix ‘CF’, it means that this is a reference to a Custom Field. The next 15 characters are the ID of the custom field. All URL parameters follow a ‘Key=Value’ convention, so after the Key (CF00NE0000002UJYd) and the ’=’ character, we get a value that represents the Name of the parent record…this is important, because it represents the human-readable value that gets pre-populated into your lookup field on the child record. NOTE: The 15-character ID that follows ‘CF’ will be a different value than what we are using here as an example; it is a unique identifier for every Custom Field in your Salesforce org.
  • &CF00NE0000002UJYd_lkid=a03E0000002255P – This is the next URL parameter. How do we know this? The ‘&’ character is our clue. Just as the ‘?’ character means that parameters are included in the URL, the ‘&’ character tells us that there is more than one parameter, and what follows the ‘&’ character is another URL parameter. In this case, the Key is ‘CF00NE0000002UJYd_lkid’. Does this look at all familiar? That’s right, it’s very similar to our previous URL parameter in that it starts out with the ‘CF’ convention for a Custom Field, and it has the same 15-character string representing the ID of the Custom Field, but you’ll notice that ‘_lkid’ is appended to the end. This stands for ‘Lookup ID’ and the corresponding value is a 15-character string representing the Record ID of the parent record. Why do we need this? Well, we may already have the Name of the parent record, but providing the ID of the parent record ensures that no additional data entry is required by the user in order for the value of the Lookup field to reference the correct parent record.
  • &retURL=%2Fa03E0000002255P – Again the ‘&’ character simply tells us that another URL parameter follows; in this case we get a Key of ‘retURL’ which tells Salesforce where to redirect the user in the event that the function is cancelled, with the Value being ‘%2F’ (the URL-encoded value for a ‘/’ character) plus the record ID of the record that was in context when the ‘New’ button on the Related List was clicked.

What do we do with all of this? Well, here’s the interesting part – that URL in and of itself is sufficient for getting a user to a screen where they can enter data for a new child record, and if they click the ‘Cancel’ button, Salesforce will know to return them to the Detail Page of the record that they were viewing when they clicked the standard ‘New’ button. But that doesn’t solve our problem – we’re not looking to return to the Detail Page when clicking ‘Cancel’ per se, we’re more interested in returning to the parent record’s Detail Page after the user clicks ‘Save’ on the new record. This URL doesn’t do the trick for us, so we need to somehow have Salesforce follow a different one when a new record is created from a Related List. But how?

The trick is to create a new Custom Button on the child object using these options:

  • Label – Whatever text you want displayed on this new button. Give it a descriptive name like ‘New (insert child object name here).”
  • Name – Give it a unique name, using only alphanumeric characters and underscores…no spaces or consecutive underscores.
  • Description – Whatever you’d like.
  • Display Type – Select “List Button” because we will be adding this to a Related List.
  • Behavior  – “Display in existing window without sidebar or header”
  • Content Source – “URL”

Now here comes the fun part. We need to construct a formula that will return a URL that provides us with all of the functionality of the standard ‘New’ button, but includes a URL parameter that tells Salesforce to return the user to the Detail Page of the parent record after this new record is saved.

This formula will be based on the URLFOR function, and at a high level will look like this:

{!URLFOR(target, id, [inputs], [no override])}

A specific example of the URLFOR function constructed to return a URL that provides us with everything we’re trying to accomplish here:

{!URLFOR( $Action.Child_Object_Name__c.New , null, [saveURL=Parent_Object_Name__c.Link, retURL=Parent_Object_Name__c.Link, CF00NE0000002aLV0_lkid=Parent_Object_Name__c.Id , CF00NE0000002aLV0=Parent_Object_Name__c.Name])}

  • target – This is where we want the user to end up when this hyperlink is clicked. In our case, we want to use $Action.Child_Object_Name__c.New, obviously changing ‘Child_Object_Name__c’ to the specific API name of your child object.
  • id – This is the ID of the record in context. This actually doesn’t pertain to us, because we’re creating a new record and will not have a record ID assigned until the record is saved. So in this case, let’s use ‘null‘ for the value of ‘id’.
  • inputs– Remember all of the URL parameters that we talked about above? Those go here using a Key = Value convention, with multiple items separated by commas. Don’t worry about not having the ‘?’ or ‘&’ characters in here, Salesforce will add them for you at runtime. So here are the URL parameters that we need:
    • saveURL=Parent_Object_Name__c.Link – Replace ‘Parent_Object_Name__c’ with the API name of your parent object. This parameter represents the secret sauce in everything we’re trying to accomplish – this is the URL that Salesforce will return the user to after the ‘Save’ button is clicked on the new record Edit Page.
    • retURL=Parent_Object_Name__c.Link – Replace ‘Parent_Object_Name__c’ with the API name of your parent object. This returns the user to a record Detail Page if the ‘Cancel’ button is pressed on the new record Edit Page.
    • CF00NE0000002aLV0_lkid=Parent_Object_Name__c.Id – Replace ‘Parent_Object_Name__c’ with the API name of your parent object, and replace the 15-character ID string contained in ‘CF00NE0000002aLV0_lkid’ with the ID of the Custom Field on the child object that looks up to the parent.
    • CF00NE0000002aLV0=Parent_Object_Name__c.Name – Replace ‘Parent_Object_Name__c’ with the API name of your parent object, and replace the 15-character ID string contained in ‘CF00NE0000002aLV0′ with the ID of the Custom Field on the child object that looks up to the parent.
  • no override – This is completely optional, and in fact we have left it out of our example. By default this is set to ‘false’, but if it were set to ‘true’ it would override any overrides that you may have in place for the ‘View’ for the record you are referencing in context.

Once you have this formula constructed, click on the ‘Check Syntax’ button. If there are errors, troubleshoot and correct them. If you get the “No syntax errors in merge fields or functions” all-clear, save this Custom Button and you’re almost done!

To get the Custom Button to appear on the Related List, edit the Page Layout(s) of the parent object.  Click on the little wrench that appears in the tab above the label of the Related List for the child object.  Expand the ‘Buttons’ section, uncheck the box next to the standard ‘New’ button, and under Custom Buttons, find your new button in the ‘Available Buttons’ section, click the ‘Add’ button (arrow facing right),  and your button should now appear under the ‘Selected Buttons’ section.  Click ‘OK’ and then save your Page Layout. Rinse and repeat for each Page Layout that needs to include this button in the Related List for the child object.

Test out your shiny new button by opening a record in the parent object, navigating down to the Related List for the child object, clicking on your custom ‘New’ button, and entering data into a new record for the child object…

  1. Does it take you back to the Detail Page for the correct record if you click ‘Cancel’?
  2. Is the correct record name populated in the Lookup field to the parent object?
  3. If you click ‘Save’ after entering data in the new record for the child object, does it take you back to the Detail Page of the parent record?
  4. Do you see the new record in the Related List for the child object?
Mike Topalovich Salesforce Technical Architect in Chicago
Mike Topalovich - Salesforce Certified Force.com Platform Developer I Mike Topalovich - Salesforce Certified Force.com Platform Developer II Mike Topalovich - Salesforce Certified Force.com Developer Mike Topalovich - Salesforce Certified Force.com Advanced Developer
Mike Topalovich - Salesforce Certified Mobile Solutions Architecture Designer Mike Topalovich - Salesforce Certified Force.com Platform App Builder Mike Topalovich - Salesforce Certified Administrator Mike Topalovich - Salesforce Certified Advanced Administrator
Mike Topalovich

Hi, I’m Mike. I help companies like yours do business in new ways with Salesforce.


I am a freelance Salesforce Developer, Architect, and CTO as well as a part time instructor for Salesforce University.


Connect with me today to discuss how I can become a part of your team on an ongoing retainer basis.


Mike Topalovich on EmailMike Topalovich on FlickrMike Topalovich on LinkedinMike Topalovich on RssMike Topalovich on Twitter

20 Comments

  1. Timothy Price

    Mike, read your post on creating a custom button on a related list. Question; I like this functionality but I would like to take it a step further. How would I proceed with a button such as “Add Multiple” hat would allow my users to add multiple line item records to the custom related list then “Save”. An example would be like a product list in an opportunity record.User selects ‘New’ button and identifies items but need to add more then ‘Saves’ rather than sing the standard ‘New’ button and adding a related record one at a time.

    Thoughts?
    Timothy

    Reply

  2. Scott Meridew

    Mike,

    When the button gets promoted from dev to prod (or qa), this solution breaks – since the custom lookup field’s ID will be different. Hard-coding the ID is not a good practice.

    Reply

    • Mike Topalovich

      Understood re: hard-coding, if you have a way to dynamically grab the custom field ID I’d love to hear it.

      The bigger point that I should edit the post with is that this discussion will all be moot shortly…Lightning Experience doesn’t support these URL hacks, so this pattern will be dying off soon.

      Reply

  3. Mark Keckeis

    Mike – super helpful. All except the part that reads ” If there are errors, troubleshoot and correct them.” 🙂

    THe record in question is a child of the Opportunity object and the field number of the lookup on the child is CF00N11000001gp4e. My urlfor looks like:

    {!URLFOR( $Action.Service_Record__c.New , null,
    [

    saveURL=Opportunity.Link,
    retURL=Opportunity.Link,
    CF00N11000001gp4e_lkid=Opportunity.Id,
    CF00N11000001gp4e=Opportunity.Name

    ],
    [true])}

    When I do the syntax error – it flags:
    CF00N11000001gp4e_lkid=Opportunity.Id,
    CF00N11000001gp4e=Opportunity.Name saying ‘Error: The Name field is required’.

    What am I screwing up?

    Many thanks,
    Mark

    Reply

    • Onttu Lindeman

      I got the same error.

      Reply

  4. Justin Calvillo

    Mike, thanks for this, I am looking to override the standard “New Opportunity” button to auto-populate the name field. This includes on the Opportunity related list off the standard accounts page. The code below works except I lose the auto population of the account lookup when I click the related list botton. Any thoughts on how to auto-populate opportunity.account.id into the lookup field from the parent record where the New Opportunity related list button is clicked?

    Thanks

    Reply

    • Mike Topalovich

      Hey, Justin. Would this work for you?

      {!URLFOR($Action.Opportunity.New , null, [retURL = Account.Id, accid = Account.Id])}

      The URL parameter called ‘accid’ seems to do the trick.

      Reply

  5. shakti

    instead of hardcoding field ids, is there way to dynamically build that like
    {!URLFOR($Action.BT_INVOICE_LINE_ITEM__c.New , null, (saveURL=BT_INVOICE__c.Link, retURL=BT_INVOICE__c.Link, $ObjectType.BT_INVOICE_LINE_ITEM__c.Fields.INVOICE__c.ID &’_lkid’=BT_INVOICE__c.Id , $ObjectType.BT_INVOICE_LINE_ITEM__c.Fields.INVOICE__c.ID=BT_INVOICE__c.Name))}

    in above syntax I am not able to append & ‘_lkid’

    Reply

    • Mike Topalovich

      If there was, we would have gone that route from the beginning. Thus the blog post.

      In the end this is all moot, however, as URL hacks will break in Lightning Experience.

      Reply

  6. Justin Calvillo

    Thanks for the responses. Mike, with it being the case that hacks don’t work in lightening, what is your recommended approach for auto population of new record screens for standard and/or custom object records to be lightning compatible or will the URLFOR that you recommended work? (Sorry for obvious question, I am a it of a newbie to advanced development)

    Reply

    • Mike Topalovich

      I am in the process of writing a replacement to this post – might not happen until October with all of the Dreamforce prep I have to do, but I will get you something. I have build out some pretty straightforward Visualforce pages and Apex controller extensions to help with the process. I haven’t tackled this as a Lightning Component / Quick Action yet, but will do that before the end of the year as well. Just need to find a way to cram it all into the 168 hours were given in a week. 🙂

      Reply

      • Justin Calvillo

        Thanks Mike. That will be great.

        Reply

  7. Sudip Kumar Mondal

    Must say,
    This was really really helpful in understanding every component of the URL.
    However, I was not able to redirect to the previous page(Very poor in making things right). 🙁

    Here’s what I have done.
    I have a custom object(History) which has a lookup relationship to Lead. This object basically makes a number of lead as “Good Number” or a “Bad Number”(Custom Requirement).

    Now, I have created a related list and a custom button aswell for that but this isn’t redirecting me to the correct history page.

    Below is the URL I am using for the custom button:
    a00/o?CF00N2800000FTwVW={!Lead.Name}&CF00N2800000FTwVW_lkid={!Lead.Id}&retURL=%2F{!Lead.Id}&saveURL=%2F{!Lead.Id}

    00N2800000FTwVW – ID for the custom field Lead__c which has a lookup to lead.

    Could you please help me with where I am going wrong?
    Thanks for your help in advance. 🙂

    Reply

    • Mike Topalovich

      For the retURL, I would use retURL={!URLFOR($Action.Lead.View, Lead.Id)}

      Reply

  8. yaizabailenYaiza

    Thanks for the post. It was really useful!

    I’m getting an error I don’t know how to fix. Maybe someone knows how to solve it.

    This is the formula I’m defining:

    {!URLFOR( $Action.My_child_object__c.New ,
    null,
    [saveURL=Account.Link,
    retURL=Account.Link,
    CF00N26000000vphU_lkid=Currency_Pair__c.Id,
    CF00N26000000vphU=Currency_Pair__c.Name])}

    And I’m getting the error:

    Error: Field $Action.Currency_Pair__c.New does not exist. Check spelling.

    Any idea? I already tried $Action.Currency_Pair__c.NewCurrencyPair; $Action.Currency_Pair__c.NewCurrency_Pair__c with the same result.

    Reply

    • Mike Topalovich

      Currency Pair is a parent object? If your referencing a relationship, you would need to use __r instead of __c. For example, Currency_Pair__r.Field_Name__c. It’s been a while since I’ve used URL hacks so I can’t remember if this works with relationships or not.

      Reply

  9. Miguel Chinchilla (@MikeBorjas)

    Hi Mike,

    Thanks for excellent example.

    I have a problem, I need to return to VisualforPage.

    How I do this?

    Best regards.

    Reply

  10. Keith Clarke

    Hi Mike,

    I’m working on making a Visualforce app that uses this technique “Lightning Ready” so if you have figured out a way to achieve the same result in “Lightning Experience” your insight would be appreciated.

    Thanks, Keith

    Reply

    • Mike Topalovich

      Hey, Keith. I haven’t tested this in LEX, but if you use a custom button to launch the Visualforce page this should work. Obviously it will still have the Salesforce Classic styling, but the functionality doesn’t depend on the UI.

      I am working on a Lightning Component to replace this, but it’s not high on the priority list so it will probably me another month or two before I can get to it.

      Reply

Leave a Reply