Thursday, March 22, 2007

Secondary Lookup

From the CRM blogs, many people asked how to add a secondary lookup to the Account and Contact form? Due to CRM 3.0's limitation, we are not able to create another relationship between account to contact or contact to account.

To add another lookup, we need to use JavaScript to inject some codes to the CRM form. The way that I am showing here will not create a relationship between the entities. Instead, it will store the Name and the GUID with the record. I used JavaScript to add a lookup fied to the form.  In this sample, I will add a secondary contact lookup to an Account.

Pro: You will able to create the lookup field and also able to use the CRM lookup box. You can create as many as you wanted. :=)

Con: If the Name changed for the contact, it will not update the name that store in the account entity. If you want to upda the name, you need to write a postcallout to update the name in the account record.

Here are the steps to create a secondary lookup:

Step 1: Create two custom attributes in the Account Entity.

Display Name: Secondary Contact
Schema Name: new_secondarycontactname
Type: String
Description: Stores the Contact name

Display Name: Secondary Contact Value
Schema Name: new_secondarycontactvalue
Type: String
Description: Stores the GUID for the Contact

 

Step 2: Add two newly created attributes to the account form.

Take out the label for "Secondary Contact Value" field. We will use JavaScript to hide the "Secondary Contact Value" field later.

 

Step 3: Insert the following code to the Account form onLoad event.

The code below will replace the Secondary Contact text field with a Lookup box.

--------------------------------------------------------------------------------

crmForm.all.new_secondarycontactvalue.style.visibility="hidden";


customSecondaryLookup("new_secondarycontactname");
  }
  catch(e)
  {
    alert(e.description);
  }
 }
}
 
function customSecondaryLookup(displayFieldName)
{
 {
   try { 
           var fld = crmForm.elements[displayFieldName];
           var temp = fld.value;
           
           if (temp.length == 0){
              fld.insertAdjacentHTML("afterEnd","<table class='lu' cellpadding='0' cellspacing='0' width='100%' style='table-layout:fixed;'><tr><td><div class='lu'>&nbsp;</div></td><td width='25' style='text-align: right;'><img src='/_imgs/btn_off_lookup.gif' id='" + displayFieldName + "' class='lu' lookuptypes='2' lookuptypenames='contact:2' lookuptypeIcons='/_imgs/ico_16_2.gif' lookupclass='BasicCustomer' lookupbrowse='0' lookupstyle='single' defaulttype='0' req='0'></td></tr></table>");
           }
           else
           {
 
fld.insertAdjacentHTML("afterEnd","<table class='lu' cellpadding='0' cellspacing='0' width='100%' style='table-layout:fixed;'><tr><td><div class='lu'><span class='lui' onclick='openlui()' oid='" + temp + "' otype='2' otypename='contact'><img class='lui' src='/_imgs/ico_16_2.gif'>" + crmForm.all.new_secondarycontactvalue.value +"</span></div></td><td width='25' style='text-align: right;'><img src='/_imgs/btn_off_lookup.gif' id='"+ displayFieldName +"' class='lu' lookuptypes='2' lookuptypenames='contact:2' lookuptypeIcons='/_imgs/ico_16_2.gif' lookupclass='BasicCustomer' lookupbrowse='0' lookupstyle='single' defaulttype='0' req='0'></td></tr></table>");
 
           }
      fld.parentNode.removeChild(fld);
      fld = crmForm.elements[displayFieldName];
      fld.value = temp;

---------------------------------------------------------------------------------


Step 4: Insert the following code to the Account form onSave event.


The code below will stripe out the GUID for the Contact from the return lookup HTML and save it to the Secondary Lookup Value field.


---------------------------------------------------------------------------------


var S_CONTACT_NAME = crmForm.all.new_secondarycontactname.parentElement.parentElement.firstChild.innerText;
 
crmForm.all.new_secondarycontactvalue.value = S_CONTACT_NAME;

---------------------------------------------------------------------------------


Step 5: Save the Account Form.


Step 6: Publish the Account Form.


Happy Programming!

21 comments:

cjakubek said...

hy darren,
how do I use the code for other entities (i.e. I want to show up an "internal coach" lookup in the contact form. refering to the user entity.)

I'm not able to identify the expressions for class='lu' lookuptypes='2' lookuptypenames='contact:2' and lookupclass='BasicCustomer'

can you hlep please???
e.g. campaign:is the following right?
calss 'lu'
lookuptypes = '4400'
lookuptypenames = 'campaign:4400'
lookupclass = campaign ?????

Darren Liu said...

lookupclass = NonTemplateCampaign

Hope this helps

Richard page said...

Hi Darren, thanks for the post.

I am wondering why the contact name disappears after I save the form, but the little contact card stays visable. Is there some way to keep the name and the card visable?

Darren Liu said...

Did you paste the form onSave code? That puts the name and the guid into the approprite field. When you open up the form, it will bring the value from those fields to build the lookup box.

rpage said...

I have cut and pasted your code and used the same naming convention as you did for the custom attributes and still do not see the name in the filed.

Darren Liu said...

var S_CONTACT_NAME = crmForm.all.new_secondarycontactname.parentElement.parentElement.firstChild.innerText;

crmForm.all.new_secondarycontactvalue.value = S_CONTACT_NAME;

Add the following line of code to see if it works:
----------------------------------

crmForm.all.new_secondarycontactvalue.click();
--------------------------------

rpage said...

Hi Darren,

I tried adding in the line of code and it still does not cause the name to reappear. Somehow just the contact card icon is loaded (which when clicked does bring me to the specified contact and not kust a look-up), but the corresponding name is not displayed when you reopen an instance of the entity. Should there not be a line of code in the OnLoad to pick it up and display it? Or as you indicated with the OnSave?

Besides that this bit of code is very nify and I can see many other applications for it.

Richard.

Darren Liu said...

I am not able to post html comments here. but for the second else statement in the form onLoad event. swap the variable "temp" with "crmForm.all.new_secondarycontactvalue.value".

It should work.

rpage said...

Hi there darren,

Tried it as well and it did not function properly. It's as if the variable place holder is erased when you press save and does not get regenerated when you open the form. You can reach me at my work address,

rpage@esbs.ca

Thank you,

christineJ said...

Hy darren,
is it possible to use fetch XML to increase the number of shown lookup objects?

if yes, where in the code do I put the fetch XML?

thx
christine

M Gothe said...

hi darren,
I've succesfully implemented this piece of code into my customization. But I realized a problem when using the custom lookup in the "Bulk Edit" Form. I get an error in line 1 of the dlg_bulkedit.aspx. Did seen this error before? Do you have any idea how to solve this problem? Marlen

christineJ said...

hy rpage, hy darren
i have implemented the code successfully.

now I have done it in another crm system and have the same error than rpage.

have you found a solution???
very urgent please!!!

christineJ said...

uuupss....

found the solution: on save event: was not activated...

everything is working fine now :-)

greets c.

Christina said...

hi darren,

i am having the same problem as rpage, where on save, the guid populates the field instead of contact.

I have added these lines as you suggested:

var S_CONTACT_NAME = crmForm.all.new_secondarycontactname.parentElement.parentElement.firstChild.innerText;

crmForm.all.new_secondarycontactvalue.value = S_CONTACT_NAME;

Add the following line of code to see if it works:
----------------------------------

crmForm.all.new_secondarycontactvalue.click();


but this did not help.
Did you are rpage ever figure out the issue?

Sam said...

I am looking for a solution to the problem of rpage and christina as well, thanks.

TIAM said...

Hy darren,

Is it possible to use fetch XML to filter data of shown lookup objects?

please help

tiampp

PdlR said...

Hi TIAM and everybody!

Yes, it's possible to use Fetch XML but you have to use crmForm.all.new_secondarycontactname instead secondarycontactvalue.

Good Luck!

John said...

Darren,
Thank you for posting the most helpful code I have seen!

Marc said...

Hello, I've tried this solution and while the process seems to work fine new_secondarycontactvalue is set to the name rather then the guid of the contact I selected. Do you know what's going on?

Thanks

Marc said...

What I need to find out is, after you choose a new secondary contact, what is the GUID of said contact before you save?

Hrvoje said...

Darren, thank you for this script that works excellently in CRM 3.0.

Do you maybe have any ideas how should it be modified to work in CRM 4.0? I have upgraded my 3.0 installation to 4.0 and it (and only it) stopped working (all other customizations not involving JavaScript are OK).

Thank you!