Custom filtering on a lookup within Microsoft Dynamics 365 CRM
Reading time: 3 - 6 minutes
Recently, we had a request from a customer to add some filtering to a couple of related lookups in a business process flow within Microsoft Dynamics 365 CRM, to reduce the amount of unnecessary data they see every day.
The system that we’ve got has a custom entity to store the issue types for them. Each record can be linked to another as a parent, so we have a couple of layers of parent and child records that allows the classification of issues to a good degree but also leaves the control of these with the customer. I then put a couple of lookups on the form so that the users have to pick a parent record (and this first one uses a view to only show parent records) and then they can pick a child issue on another lookup which has filtering based on the first lookup.
So this is fairly straightforward stuff involving views and filtering on lookups so that, after a small amount of set-up, it was working fine. So you can imagine my confusion when a bug was logged to say that none of the filtering was working and, when I saw a screenshot of this, realised that the lookups were also being used in a business process flow.
Hmm, that does present a problem. The business process flow within Microsoft Dynamics 365 CRM doesn’t give us any sort of option to add this in.
After a quick bit of investigation, I discovered that there were some options here. There’s JavaScript code that allows filtering of lookups and we can reference the business process flow as part of this, so there was hope that we could solve this issue. Very quickly, a couple of methods jumped out as the possible answers: AddCustomFilter and AddPreSearch.
I had all sorts of fun trying to get this working as it needed to be done in two parts. The first part was to filter the parent issues – this is going to be the same filter every time so should be easier. The second part was to filter the child issues and would be dependent on the parent so would have to be done on the fly as we wouldn’t know what the parent issue was going to be until it was set. I thought the parent issues would be the best place to start.
Looking at a few resources I found proved valuable. So, let’s begin with the first function declaration:
var filterDefinition2 = { preFiltering: function () {
"use strict";
if (Xrm.Page.getControl("header_process_tm_mainissue") != null) {
Xrm.Page.getControl("header_process_tm_mainissue").addPreSearch(filterDefinition2.preSearchIssues);
}
else
return;
},
We’re simply creating that function with a prefiltering option, we’ve then got an ‘if’ statement to make sure the field is actually on the business process flow (along with the “header_process_” to point it at the field in the business process flow) before adding the filtering to the field. This is there the next part comes in:
preSearchIssues: function () {
"use strict";
var filterBpf = '<filter type="and"><condition attribute="statecode" operator="eq" value="0" /><condition attribute="tm_issuetype" operator="eq" value="100000000" /></filter>';
Xrm.Page.getControl("header_process_tm_mainissue").addCustomFilter(filterBpf);
}
};
So we’re just declaring a variable, adding in the filtering part from the FetchXML query and then applying it to the field on the business process flow in Microsoft Dynamics 365 CRM. The only thing to point out was getting the FetchXML, which I did using Advanced Find, defining my query in there (you can probably see this has two conditions; that the record is active and its type is a parent issue which is from an option set), then clicking on the Download FetchXML button and extracting the <filter> tag from the output.
The last thing to do was to call the code from the form. This lives in the onload event with the function call of “filterDefinition2.preFiltering”.
Once tested, this code worked, and it filtered the lookup as expected. It also looked like this code didn’t run until I clicked on the lookup in the business process flow, which was good as the next part would need this functionality in place. This was just a case of modifying the filter to get what was needed so I duplicated the first bit of code then updating its name and the field it sits against:
var filterDefinition3 = { preFiltering: function () {
"use strict";
if (Xrm.Page.getControl("header_process_tm_subissue") != null) {
Xrm.Page.getControl("header_process_tm_subissue").addPreSearch(filterDefinition3.preSearchIssues);
}
else
return;
},
The second function needed a bit more work. To start with, I used Advanced Find again to get the FetchXML for one of the parent issues:
This yielded the filter criteria in the FetchXML of:
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
<condition attribute="tm_parentissue" operator="eq" uiname="Escalation" uitype="tm_issuetype" value="{CD2AD5F9-4D0A-EC11-B6E6-000D3A86F29E}" />
</filter>
So, in that second function, I just needed to modify the ‘filterBpf’ variable with this but filling in the name and ID with the values from the main issue field:
preSearchIssues: function () {
"use strict";
var lookupobject = Xrm.Page.getAttribute("tm_mainissue").getValue();
var theName = lookupobject[0].name;
var theGUID = lookupobject[0].id;
var filterBpf2 = '<filter type="and"><condition attribute="statecode" operator="eq" value="0" /><condition attribute="tm_parentissue" operator="eq" uiname="' + theName + '" uitype="tm_issuetype" value="' + theGUID + '" /></filter>';
Xrm.Page.getControl("header_process_tm_subissue").addCustomFilter(filterBpf2);
}
};
Hopefully, you can see in the code that the lines in red are simply using standard code to get the lookup’s name and ID which are then being used in the filter using the code we know works. The last thing to do is to add another call to this function from the form (“filterDefinition3.preFiltering”) and that was it!
Now, you should see that the only thing that defines this as a business process flow function is the names of the fields that are being filtered as they begin with “header_process_”. There’s no reason why you couldn’t use these on the form by referring to form fields if you wanted to have different filtering on a lookup based on dynamic values.
For more information on the business process flow within Microsoft Dynamics 365 CRM, please contact your Account Manager and they will be able to assist further.