Apply filtering to subgrid’s inline lookup in CRM

A common requirement is to apply filtering to a subgrid’s inline lookup on CRM form. For example, you might want to allow users to add only contacts of a particular account (selected in another field) to a contact subgrid on the form.

Just to be clear, the highlighted lookup below is what we want to filter (and what this post is about). There are several posts on the web that talk about filtering the subgrid; but they are about filtering the records that appear on a subgrid, and not the records that appear in the inline lookup that is use to add a record to the subgrid.

1-lookup

Note: The method described in this post is unsupported.

The inline lookup of a subgrid is actually a normal lookup control (more or less), and therefore has the same methods as a normal lookup control. We therefore can apply filtering to this control using the standard addPreSearch and addCustomFilter methods of the control.

It is however difficult to gain access to this control (for a subgrid) as it is not exposed in any of the API. We therefore will need to use unsupported methods to access it.

The subgrid’s lookup control is actually given a control name by CRM, and this name is based on the name of the subgrid. For example, if the subgrid is named grdContacts in the form, the name of the subgrid’s lookup control would be lookup_grdContacts. We can use this name to retrieve the lookup control – but wait..

While you can use Xrm.Page.getControl(“lookup_grdContacts”) to retrieve the subgrid’s lookup, you can only do so after the user has clicked the + icon on the subgrid to bring up the lookup control. Therefore, our code to retrieve the lookup control and call the addPreSearch and addCustomFilter methods on it would need to happen within (or triggered by) the click event of the + icon.

The HTML ID of the + icon has the format [gridName]_addImageButton, e.g. grdContacts_addImageButton. Using this ID we can retrieve the + icon from the DOM and attach code to the click event to retrieve the lookup control and apply our filter.

Below is the code. Please review the in-code comments.


function setSubgridLookupFiltering() {
	var subgridAddButtonId = "grdContacts_addImageButton";

	//Try to get the element from both the current and the parent document.
	var subgridAddButton = document.getElementById(subgridAddButtonId) || window.parent.document.getElementById(subgridAddButtonId);

	//This script may run before the subgrid has been fully loaded on the form. If this is the case,
	//delay and retry until the subgrid has been loaded.
	if (subgridAddButton == null) {
		setTimeout(setSubgridLookupFiltering, 2000);
		return;
	}

	//Local function to retrieve the lookup control and apply the filter. We will queue this function in the click event handler of the
	//Add button's click event.
	var getSubgridLookupAndAddFilter = function() {
		var subgridLookup = Xrm.Page.getControl("lookup_grdContacts");

		//Delay and retry until we can locate the lookup.
		if (subgridLookup == null) {
			setTimeout(getSubgridLookupAndAddFilter, 200);
			return;
		}

		//This is a custom property we are tagging on to the lookup control to ensure that we will
		//apply the custom filter only once when the Add button is first clicked.
		if (subgridLookup.customFilterAdded) {
			return;
		}

		subgridLookup.addPreSearch(function() {
			//Standard logic to build up the filter query string
			var filterQuery = "";

			//filterQuery = "<filter type='and'.....></filter>";
			//..
			//..

			//Standard call to add filter to the lookup control
			subgridLookup.addCustomFilter(filterQuery, "contact");
		});

		//Mark the fact that we have already added the filter so that we won't do it again the next time the user clicks the Add button.
		subgridLookup.customFilterAdded = true;
	};

	//Attach the function to retrieve the lookup and apply the filter to the Add button's click event. Remember that we
	//can only get the lookup after the user has clicked the Add button.
	subgridAddButton.addEventListener("click", function() {
		setTimeout(getSubgridLookupAndAddFilter, 200);
	});
}

Here is another post that uses a similar approach: http://www.bobylog.com/microsoft-dynamics-crm-2015-subgrid-lookup-filter/. This however retrieves the lookup control using a magic sequence of object properties, which differ between versions of CRM, and in my opinion is more prone to breaking in future versions.

About Bernado

Based in Australia, I am a freelance SharePoint and Dynamics CRM developer. I love developing innovative solutions that address business and everyday problems. Feel free to contact me if you think I can help you with your SharePoint or CRM implementation.
This entry was posted in CRM. Bookmark the permalink.

2 Responses to Apply filtering to subgrid’s inline lookup in CRM

  1. Bjorn I says:

    Hey. Great solution, unfortunately it doesn’t work with CRM 2013. After clicking the ‘+’ button the code is never able to get the lookup control. I am able to find it in the HTML, but Xrm.Page.getControl always returns null for the correct id. Any advice?

  2. mardukes says:

    Doesn’t seem to work in D365. One cannot turn of filtering on the grid without losing the 3 controls. And while it is set to associated records, that filter does not appear to be replaced. Any way to validate the lookup_opportunityproductsGrid control was found?

    ps- if the only part that is unsupported is the DOM script, how about hanging the function on the button itself using Ribbon tool?

Leave a comment