11 May 2008

The mysterious CRM Lookup (II)

4. Now, how can we set/filter the lookup content? Because CRM3 and CRM4 are so different in lookup, so the solution is different. Let’s see a common example: In the Account record, only show the account owned contacts in the Primary Contact (primarycontactid) lookup.

a. CRM 3.0


/* CRM 3.0: only show account owned contacts in the primarycontactid lookup : Form.onLoad() */
if (crmForm.FormType == 2 && crmForm.ObjectId != null)
{
crmForm.all.primarycontactid.lookupbrowse = 1;
crmForm.all.primarycontactid.additionalparams = "fetchXml="
+ "<fetch mapping='logical'><entity name='contact'><all-attributes /><filter>"
+ "<condition attribute='accountid' operator='eq' value='" + crmForm.ObjectId + "' />"
+ "</filter></entity></fetch>";
}


b. CRM 4.0

As far as I know, there are two unsupported ways to do that. Because we don't need a complicated fetchxml in this case, we so could use the first approach:

1. Customize Contact entity, open Contacts Lookup View, click 'Add Find Column', add the Parent Customer (parentcustomerid), save and publish it.
2. Customize Account entity, put the following code into Form.onLoad() :


/* CRM 4.0: only show account owned contacts in the primarycontactid lookup : Form.onLoad() */
if (crmForm.FormType == 2 && crmForm.ObjectId != null)
{
var name = crmForm.all.name.DataValue;
crmForm.all.primarycontactid.additionalparams = 'search=' + name;
}

It's a nice approach which used the 'search' feature of the CRM lookup. When this parameter is specified it defaults the search string in the lookup dialog and applies the search when the dialog is opened.


It's great, now let's change the requirement:
How about: Only show the Parent Account (parentaccountid) owned contacts in the Primary Contact (primarycontactid) lookup.

We still need to repeat step (1), and then in the step (2):


/* CRM 4.0: only show parent account owned contacts in the primarycontactid lookup: Form.onLoad() */
FilterLookup = function(source, target)
{
if (IsNull(source) IsNull(target)) { return; }
var name = IsNull(source.DataValue) ? '' : source.DataValue[0].name;
target.additionalparams = 'search=' + name;
}

Also, we need to put the following code into parentaccountid.onChange():


/* CRM 4.0: only show parent account owned contacts in the primarycontactid lookup : parentaccountid.onChange() */
FilterLookup(crmForm.all.parentaccountid, crmForm.all.primarycontactid);


It's great too, now how about we add another requirement on the above example:
The Primary Contact (primarycontactid) should be automatically selected when this contact is the primary contact of the selected Parent Account (parentaccountid).

Although we could do it through AJAX, we can also do it through CRM 4.0 lookup field automatic resolutions technique. Thanks for Adi Katz, let's start from begin:

(1) Turn off the Parent Account (parentaccountid) "automatic resolutions in field" feature by double click the field on the Form.
(2) Put the following codes in Account.onLoad():


function OnAfterAccountSelect()
{
var contactLookup = crmForm.all.primarycontactid;
if( contactLookup.DataValue != null ) {return;}

contactLookup.AutoResolve = 1;
var accountLookup = crmForm.all.parentaccountid;
primaryContact = accountLookup.items[0].keyValues.primarycontactid;

contactLookup.SetFocus();
contactDiv = document.all.primarycontactid_d.getElementsByTagName("DIV")[0];
contactDiv.innerText = primaryContact.value;
contactLookup.Lookup( true , true , primaryContact.value , true );
}

function OnCrmPageLoad()
{
crmForm.all.parentaccountid.attachEvent( "onafterselect" , OnAfterAccountSelect );
}

OnCrmPageLoad();


The second approach which can deal with some complicated conditions will be introduced in the next post. :)

28 comments:

Benjamin Rutledge said...

Is there a way to use this lookup filter technique to filter one lookup field based on a value selected in another?

Jim Wang said...

Yes, absolutely. Show me what you need.

Anonymous said...

This artical helped me alot. thanx.

I need to know if there is a way to use this to filter one loopup field based on a value selected in another- i have two objects - city and street that will be connected using city id.
according to the value chosen in city, i would like to filter the street lookup.

Anonymous said...

If the account name has some international characters this first approach will not work. In the Search field the name shows up with small squares instead of the international characters.

I cannot get the second approach working at all. I get all the accounts, not only the one's belonging to my parent customer. After this it throws me an error when I close the form.

Anonymous said...

Solved the first problem.

You need to use the encodeURIComponent(name) and then all characters will be transferred corectly to the Search box.

The second one I don't get working.

abipeter said...

Hi,
I have modified the system lookup in Oppurtunity to fetch only accounts and its working fine. However, i found that the new button is not working from the lookup browse window. any idea why its not working...

Thanks

abipeter said...

This is the Request URL:

http://crmserver/PITS/_controls/lookup/lookupsingle.aspx?class=BasicCustomer&objecttypes=1,2&browse=1&search= 'fetch mapping='logical'' 'entity name='account'' 'attribute name='accountnumber' ' 'attribute name='name' ' 'filter' 'condition attribute='new_managementpersonid' operator='not-null' ' 'condition attribute='new_userid' operator='not-null' ' '/filter' '/entity> 'fetch' &selObjects=1&findValue=0&ShowNewButton=1&ShowPropButton=1&DefaultType=0


the error was Invalid parameter 'selObjects=1' in Request.QueryString

please help me, since this lookup field fetch from contacts and accounts i changed it to fetch only accounts.

Nate said...

I love it. Thanks Jim!

Anonymous said...

I guess you cannot filter the lookup by date using second approach.

Marc de Ruijter said...

Jim,

In a Phone Call form, when a user selects the Contact (in the "From" field) we want to automatically populate the parentcustomer ('company') in another custom field.
Since i am new to CRM customization i was hoping you could show me how this is done.

Anonymous said...

酒店經紀PRETTY GIRL 台北酒店經紀人 ,禮服店 酒店兼差PRETTY GIRL酒店公關 酒店小姐 彩色爆米花酒店兼職,酒店工作 彩色爆米花酒店經紀, 酒店上班,酒店工作 PRETTY GIRL酒店喝酒酒店上班 彩色爆米花台北酒店酒店小姐 PRETTY GIRL酒店上班酒店打工PRETTY GIRL酒店打工酒店經紀 彩色爆米花

Unknown said...

Is it in any way possible to do this for a N:N relationship?

I've tried, but since there is no field for a N:N relationship to base its

Ross said...

Can this be used to select a lookup (say the parent account on the account form) and default in the primary contact from the parent account you have selected? I think it can but am unsure exactly how it would work... Thx

Unknown said...

Hello, I have added the following script that filters the target options based on the relationship it has with the source attribute. Everything works fine except that I have danish characters in the source attribute that the target attribute doesn't recognize. That is I look up in the S lookup =Æl and then in the P lookup it shows=[]l any ideas?

Thanks,

Patrick


Script onload form:
document.FilterLookup = function(source, target)
{
if (IsNull(source) || IsNull(target)) { return; }

var name = IsNull(source.DataValue) ? '' : source.DataValue[0].name;

target.additionalparams = 'search=' + name;
}
and on change on the source attribute:
document.FilterLookup(crmForm.all.key_sid, crmForm.all.key_pid);

Unknown said...

I want to filter out contacts in a lookup based on a customised field; i.e. my customised contact entity has a new_StaffID attribute and I want to only look up contacts where new_StaffID is not null. All the examples I see are about matching to a positive value; can this be done?

Unknown said...

JIM,

All is well, but thereis one more senario. If i want to filter the lookup depending on two values then it is hard one. do u have any solution for this.

kenn said...

Hi, is it possible to filter on the subject lookup? It brings up the lookupsubject.aspx page instead of hte lookupsingle.aspx..

Jorn van Veelen said...

Hi Jim,

Great solution, but... it skips some special characters.
For example: Ä, Ö and Ü. So if the account name contains 'Käse', the lookup will be filtered on 'Kse'.

Do you know if there's a solution available for this? Thanks!

Unknown said...

Hi,

great solution. But it doest work if for example an account name has an "&" in it. Anyone who knows a fix for that?

Thanks in advanced

victorcampos30 said...

Hi, Jorn Van Veelen

target.additionalparams = 'search=' + encodeURIComponent(name);

This solve special charachter

See youu

Jij said...

Hello Jim
I have a problem here while trying to implement your approach. Would be great if you could give me a solution.
I have 'LKUP 1' based on which 'LKUP 2' has to be filtered. By using your approach, I am able to filter LKUP 2 based on LKUP 1. But the problem is that I dont want the user to be in a position to 'search' on the Lookup dialog. So I tried to add the condition, LKUP 2.lookupbrowse = 1. As a result, the lookup dialog does not display the Search option, but at the same time, the filtering does not happen, and I can see all LKUP 2 records instead of the filtered set. If I remove the above line of code, filtering starts to work again. Would you be able to give me some insights?

Thank You
Jij

Nathan said...

We have been using this method for quite some time on our Primary contact field on the account.

We have recently added a lot of accounts and contacts and we now have almost 500,000 contacts. The filtered lookup window now takes 20-50 seconds to return the contacts for that account. Is this still the best way to filter the contacts? Is there a faster way to do this?

Andy said...

Jim,

Did you ever come across this?

If you have a record with two spaces in its name, like some of the MS Sample data (i.e. "Blue Company (sample)", which is a sample account in CRM Online), using the below script to get the name of that record when it's the value for a lookup field will remove the extra space.

lookupItem[0].name = "Blue Company (sample)", not "Blue Company (sample)"

The extra space is gone.



Strange, huh? Is this by design? You can actually see that the actual name property of the lookup field which is displayed in the lookup (the blue link text) is also missing the extra space. As a matter of fact, you can put 10 spaces in the name field, but in lookups it will show up with only one space.

I guess it's for neatness, but it makes this filtered lookup code break.

Albarada said...

i need to filter a lookup field related to contacts to show only the contacts with the type of sales person. Any ideas?
Thank you

Unknown said...

I want to filter Existing Activity Lookup view on Cases, this scenario is different as i want those activities only which are related to the Customer of the case.

STH said...

Did anyone ever find a solution to Andy's comment about double spaces? We have the same problem.

Quân Đào said...

học kế toán thực hành cấp tốc
học kế toán thực hành cấp tốc
học kế toán thực hành tại cầu giấy
học kế toán thực hành tại thanh xuân
]học kế toán thực hành tại hà đông
học kế toán thực hành tại long biên
học kế toán thực hành tại long biên
học kế toán thực hành tại hải phòng
học kế toán thực hành tại bắc ninh
học kế toán thực hành tại tphcm
học kế toán thực hành tại quận 3
học kế toán thực hành tại hải phòng
học kế toán thực hành tại bắc ninh
học kế toán thực hành tại bình dương
học kế toán thực hành tại biên hòa
học kế toán thực hành tại vinh
học kế toán thực hành tại vinh
học kế toán thực hành tại huế
học kế toán thực hành tại đà nẵng
học kế toán thực hành tại đà nẵng
học kế toán thực hành tại đà nẵng
học kế toán thực hành tại hải dương
học kế toán thực hành tại hưng yên
học chứng chỉ kế toán
học kế toán ở đâu tốt

Ahana said...

Great! you explained this topic very briefly and understandably. I'm going to share this with our friends. Thank you for sharing! best full stack developer course in Noida