Accessing Related Object fields in custom button. (URL HACK) - Answers - Salesforce Trailblazer Community
Trailblazer Community
Ask Search:
Chris DuncombeChris Duncombe 

Accessing Related Object fields in custom button. (URL HACK)

Having a real brain freeze here.

I am using some URL hacking to auto fill some fields on a custom object.

USE CASE

I have a custom object 'Operations Action' that is related to a case. My Case object has the standard Account fieldm but we have an additional custom lookup to account called 'End Customer Account' (End_Customer_Account__c). This is used to hold the actual end customer. Many times they match if the case is for a customer. However for partners, the Partner account would be in the standard Account field but the customer they are logging the case on behalf of would go in the End_Customer_Account__c field.

ISSUE

I am trying to create a simple custom button that auto populates the shipping address of the End Customer Account. The reason that we are not using a formula is that we want the end user to have the ability to overwrite the value. So really just want to set it to the End Customer Account Fields Shipping Address on the Case as a default, and they can overwrite it if they want.

Am I not allowed to use Related objects in custom buttons? This is what I have

/a6M/e?CF00N80000005QYo9={!Case.CaseNumber}
&CF00N80000005QYo9_lkid={!Case.Id}
&CF00N80000005QYo5=
{!IF(ISBLANK(Case.End_Customer_Account__c),
Case.Account,
Case.End_Customer_Account__c)}

&CF00N80000005QYo5_lkid=
{!IF(ISBLANK(Case.End_Customer_Account__c),
Case.AccountId,
Case.End_Customer_AccountId__c )}

&retURL=%2F{!Case.Id}

&00N80000005QYoN={!Case.End_Customer_Account__r.ShippingStreet}  //NOT WORKING



I keep getting the

'Error: Field Case.End_Customer_Account__r.ShippingStreet does not exist. Check spelling'

It works fine if I use the Account Field

&00N80000005QYoN={!Case.Account.ShippingStreet}

I have know I can create formula fields on the case that pull in the Shipping Address Fields for the related account, and then use those in this custom button, but I would rather not create 6 custom fields on the case just for this custom button.

Am I missing something? Can I not directly access related object fields in this custom button? I can't seem to find any documentation on this and just want to make sure I absolutely have to before creating the formula fields in order to make this work.
Best Answer chosen by Chris Duncombe
Deepak AnandDeepak Anand
Chris,

Well, it's the basic fact - "I cannot directly access related object fields in this custom button(or Custom Buttons & Links in Force.com)" that stops us here. In other words Merge Fields available in Custom Buttons & Links cannot access Related Object Fields rather only those fields on the record in context.

And yes creating 6 Custom Formula Fields that too traversing relations is certainly an overkill. What you could do is to use the Force.com AJAX Toolkit and then query the fields from the Related Object via a SOQL, construct the URL in JavaScript with the result returned via the query and then use the window.open(...) or location.replace(...) to open the contstructed URL.

All Answers

Deepak AnandDeepak Anand
Chris,

Well, it's the basic fact - "I cannot directly access related object fields in this custom button(or Custom Buttons & Links in Force.com)" that stops us here. In other words Merge Fields available in Custom Buttons & Links cannot access Related Object Fields rather only those fields on the record in context.

And yes creating 6 Custom Formula Fields that too traversing relations is certainly an overkill. What you could do is to use the Force.com AJAX Toolkit and then query the fields from the Related Object via a SOQL, construct the URL in JavaScript with the result returned via the query and then use the window.open(...) or location.replace(...) to open the contstructed URL.
This was selected as the best answer
Chris DuncombeChris Duncombe
@Deepak,

    Thanks for confirming what I thought to be true, I just couldn't find it actually written in the docs anywhere.  Do you have some links to confirm I can look at just for my own sanity.

I will write the button in javascript instead as you suggest.  Thanks 


Deepak AnandDeepak Anand
I really don't have any but lemme search and this is what I have found thro' practice(I get a chance to write at-least one Custom Button a day from this amazin Community).

Let me know if you're stuck[I know you'll not be ;)]
Chris DuncombeChris Duncombe
@ Deepak, No worries.  I couldn't really find much written either.  Just making sure I wasn't missing something obvious.  

Like many thingsin SF, sometimes you have to accept some things as fact based on pure experience rather than documentation.  Thanks a lot for your confirmation I wasn't crazy.  I'll post the button once I write it.
Chris DuncombeChris Duncombe
Here's the button that works perfectly based on your suggestion to use JS.  Thanks a lot.

{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 

var url = '/a6M/e?CF00N80000005QYo9={!Case.CaseNumber}&CF00N80000005QYo9_lkid={!Case.Id}'

var myquery = "SELECT Id, Name, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = '{!Case.End_Customer_AccountId__c}' limit 1";

result = sforce.connection.query(myquery); 
records = result.getArray("records"); 

if(records[0]){ 
     var EndCustomerAccount = records[0]; 
     url += '&CF00N80000005QYo5=' + EndCustomerAccount.Name;
     url += '&CF00N80000005QYo5_lkid=' + EndCustomerAccount.Id;
     url += '&00N80000005QYoN=' + EndCustomerAccount.ShippingStreet;
     url += '&00N80000005QYoK=' + EndCustomerAccount.ShippingCity;
     url += '&00N80000005QYoM=' + EndCustomerAccount.ShippingState;
     url += '&00N80000005QYoO=' + EndCustomerAccount.ShippingPostalCode;
     url += '&00N80000005QYoL=' + EndCustomerAccount.ShippingCountry;
}else{
     url += '&CF00N80000005QYo5={!Case.Account}';
     url += '&CF00N80000005QYo5={!Case.AccountId}';
     url += '&00N80000005QYoN={!Account.ShippingStreet}';
     url += '&00N80000005QYoK={!Account.ShippingCity}';
     url += '&00N80000005QYoM={!Account.ShippingState}';
     url += '&00N80000005QYoO={!Account.ShippingPostalCode}';
     url += '&00N80000005QYoL={!Account.ShippingCountry}';
}
window.parent.open(url, "_self");


Chris DuncombeChris Duncombe
@Deepak, 

     Hoping to get some help from you as I know your a JS wiz.  I have put my final button below.  It works fine, except when the shippingstreet is multiple lines.  It throws the 'unterminated string' error.

I have tried using JSENCODE(), JSINHTMLENCODE() and SUBSTITUTE() functions all with no luck.  I can get it to sdave without error, but still get the same error when i click the button if the shippingstreet has multiple lines.  I am sure that the solution will include one or more of these functions and I am just not using it correctly.  Can you try to help me get this to work with multiple lines in ShippingStreet?  Thanks

I have tried these with no luck

{!JSENCODE(Account.ShippingStreet)}';

{!JSINHTMLENCODE(Account.ShippingStreet)};

{!SUBSTITUTE(JSENCODE(Account.ShippingStreet), '\n', '<br>'};

{!SUBSTITUTE(JSINHTMLENCODE(Account.ShippingStreet), '\n', '<br>'};


{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 

var url = '/a6M/e?CF00N80000005QYo9={!Case.CaseNumber}&CF00N80000005QYo9_lkid={!Case.Id}&00N80000005Qfyi={!Case.Appliance_Version__c}&00N80000005Qfys={!Case.Appliance_Revision_Level__c}' 

var accQuery = "SELECT Id, Name, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = '{!Case.End_Customer_AccountId__c}' limit 1"; 

result1 = sforce.connection.query(accQuery); 
AccRecords = result1.getArray("records"); 

var conQuery = "SELECT Id, Name, Phone FROM Contact WHERE Id = '{!Case.End_Customer_ContactId__c}' limit 1"; 

result2 = sforce.connection.query(conQuery); 
ConRecords = result2.getArray("records"); 

if(AccRecords[0]){ 
    var EndCustomerAccount = AccRecords[0]; 
    url += '&CF00N80000005QYo5=' + EndCustomerAccount.Name; 
    url += '&CF00N80000005QYo5_lkid=' + EndCustomerAccount.Id; 
    url += '&00N80000005QYoN=' + EndCustomerAccount.ShippingStreet; 
    url += '&00N80000005QYoK=' + EndCustomerAccount.ShippingCity; 
    url += '&00N80000005QYoM=' + EndCustomerAccount.ShippingState; 
    url += '&00N80000005QYoO=' + EndCustomerAccount.ShippingPostalCode; 
    url += '&00N80000005QYoL=' + EndCustomerAccount.ShippingCountry; 
}else{ 
    url += '&CF00N80000005QYo5={!Case.Account}'; 
    url += '&CF00N80000005QYo5_lkid={!Case.AccountId}'; 
    url += '&00N80000005QYoN={!Account.ShippingStreet}'; 
    url += '&00N80000005QYoK={!Account.ShippingCity}'; 
    url += '&00N80000005QYoM={!Account.ShippingState}'; 
    url += '&00N80000005QYoO={!Account.ShippingPostalCode}'; 
    url += '&00N80000005QYoL={!Account.ShippingCountry}'; 
} 
if(ConRecords[0]){ 
    var EndCustomerContact = ConRecords[0]; 
    url += '&CF00N80000005QfmD=' + EndCustomerContact.Name; 
    url += '&CF00N80000005QfmD_lkid=' + EndCustomerContact.Id; 
    url += '&00N80000005Qfyd=' + EndCustomerContact.Phone; 
}else{ 
    url += '&CF00N80000005QfmD={!Case.Contact}'; 
    url += '&CF00N80000005QfmD_lkid={!Case.ContactId}'; 
    url += '&00N80000005Qfyd={!Contact.Phone}'; 
} 
window.parent.open(url, "_self");


Deepak AnandDeepak Anand
Chris,

I tried JSENCODE and it did work. So I am guessing that I haven't replicated it successfully and I am sure I am missing something:
User-added image

And the code that I used:
console.log('{!JSENCODE(Lead.Street)}');
Chris DuncombeChris Duncombe
Deepak,

     Added the same line to the top line of my button.  If I use a single line address, works fine.


{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")} 

console.log('{!JSENCODE(Account.ShippingStreet)}'); 

var url = '/a5J/e?CF00NS00000011W75={!Case.CaseNumber}&CF00NS00000011W75_lkid={!Case.Id}&00NS000000123kU={!Case.Appliance_Version__c}&00NS000000123kZ={!Case.Appliance_Revision_Level__c}' 

var accQuery = "SELECT Id, Name, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = '{!Case.End_Customer_AccountId__c}' limit 1"; 


.........//Rest of my code




User-added image



If I then go and add a second line to the address, it no loner works and I get the JS error

User-added image




User-added image


I feel like I am missing something very simple but for the life of me cannot figure it out.  
Chris DuncombeChris Duncombe
I should mention that it doesnt even log to the console even though its the first line.  Just throws the error.  
Deepak AnandDeepak Anand
Chris,

This may seem dumb: Can you erase everything in Street and then type it back!

Honestly, I tried with that same Address both on Lead and on Account and it just worked(with the JSENCODE)!
User-added image
Chris DuncombeChris Duncombe
Just tried it....no luck.  It definitely makes me feel better though that I am not the only one it doesnt make sense to.  At least I'm not going crazy.

User-added image
Chris DuncombeChris Duncombe
I mean yes, we certainly can.  I don't want to take up too much of your time though....