How to Filter a Lookup Field Based on Another Lookup in Dynamics 365
How to Filter a Lookup Field Based on Another Lookup in Dynamics 365
Introduction
In Microsoft Dynamics 365 CRM, lookup fields are commonly used to establish relationships between entities. However, there are situations where users should only see specific records in a lookup based on the value selected in another lookup field.
For example:
- Filter Contacts based on the selected Account.
- Filter Cities based on the selected Country.
- Filter Opportunities based on the selected Customer.
- Filter Projects based on the selected Client.
This can be achieved using JavaScript and the Dynamics 365 Xrm API. In this article, we'll learn how to filter a lookup field based on another lookup field in Dynamics 365.
Business Scenario
Parent Lookup: Account Lookup
Child Lookup: Contact Lookup
When a user selects an Account, the Contact lookup should only display contacts related to that Account.
Without Filtering
Users can see all Contacts.
With Filtering
Users only see Contacts associated with the selected Account.
This improves data quality and user experience.
Solution Overview
We'll use:
- JavaScript Web Resource
- addPreSearch()
- addCustomFilter()
- FetchXML Filter
The filtering process works as follows:
- User selects an Account.
- JavaScript retrieves the Account ID.
- A custom filter is applied to the Contact lookup.
- Only matching Contacts are displayed.
Step 1: Create a JavaScript Web Resource
new_FilterLookup.js
Step 2: Add the JavaScript Code
var FilterLookup = {
filterContactLookup: function (executionContext) {
var formContext = executionContext.getFormContext();
var accountLookup = formContext.getAttribute("parentcustomerid");
if (accountLookup != null && accountLookup.getValue() != null) {
var accountId = accountLookup.getValue()[0].id.replace("{", "").replace("}", "");
formContext.getControl("primarycontactid").addPreSearch(function () {
var filterXml =
"<filter type='and'>" +
"<condition attribute='parentcustomerid' operator='eq' value='" + accountId + "' />" +
"</filter>";
formContext.getControl("primarycontactid").addCustomFilter(filterXml, "contact");
});
}
}
};
Step 3: Register the Function
Open the form and configure the following:
Form Properties
new_FilterLookup.js
OnChange Event
Field:
parentcustomerid
Function:
FilterLookup.filterContactLookup
Enable:
Pass execution context as first parameter
Step 4: Publish Changes
Save and publish all customizations.
How the Code Works
Get Selected Account
var accountId = accountLookup.getValue()[0].id;
Retrieves the selected Account record.
Register PreSearch Event
addPreSearch()
Executes before the lookup search opens.
Apply Custom Filter
addCustomFilter()
Adds a FetchXML filter to the lookup.
Filter Contacts
<condition attribute='parentcustomerid'
operator='eq'
value='ACCOUNTID' />
Only Contacts linked to the selected Account are displayed.
Example: Country and City Lookup
Suppose you have:
Country Lookup
new_country
City Lookup
new_city
Filter cities by selected country:
var filterXml =
"<filter type='and'>" +
"<condition attribute='new_country' operator='eq' value='" + countryId + "' />" +
"</filter>";
Result:
- India → Chennai, Hyderabad, Bangalore
- USA → New York, Chicago, Dallas
Users only see relevant cities.
Advanced Example Using FetchXML
var filterXml =
"<filter type='and'>" +
"<condition attribute='statecode' operator='eq' value='0' />" +
"<condition attribute='parentcustomerid' operator='eq' value='" + accountId + "' />" +
"</filter>";
This filters:
- Active Contacts only
- Related to selected Account
Best Practices
Use PreSearch Event
Always use addPreSearch() for lookup filtering.
Validate Null Values
Always check whether the parent lookup contains a value.
Use Entity Schema Names
Use schema names instead of display names.
Keep Filters Lightweight
Avoid large FetchXML queries that affect performance.
Test Security Roles
Verify users can access the records returned by the filter.
Common Use Cases
- Account → Contact
- Country → City
- Customer → Opportunity
- Department → Employee
- Project → Task
Troubleshooting
Lookup Not Filtering
- Verify JavaScript is loaded.
- Verify event registration is correct.
- Verify function name is correct.
No Records Displayed
- Verify relationship exists.
- Verify schema names are correct.
- Verify Account ID is being retrieved.
JavaScript Errors
Use browser Developer Tools (F12) to inspect console errors.
Conclusion
Filtering lookup fields based on another lookup field is a common Dynamics 365 requirement that improves data accuracy and user experience.
Using JavaScript with addPreSearch() and addCustomFilter() allows you to dynamically control which records users can select.
Whether you're filtering Contacts by Account, Cities by Country, or Opportunities by Customer, this approach provides a clean and efficient solution within Dynamics 365.