Filtering Dynamics 365 Subgrids Without Relationships: A JavaScript-Only Approach Using setFilterXml - CloudFronts

Filtering Dynamics 365 Subgrids Without Relationships: A JavaScript-Only Approach Using setFilterXml

In Microsoft Dynamics 365, subgrids are a powerful way to display related records on a form. But what happens when:

  • a. The subgrid’s entity has no relationship with the form’s main entity?
  • b. Or when the filtering criteria cannot be placed inside the view?
  • c. Or when the filter needs to be dynamic, based on field values entered on the form?

Out-of-the-box, Dynamics 365 doesn’t give us many options here. We can select a view, but we cannot apply dynamic filters unless the entities are directly related or the criteria already exist in the view’s FetchXML.

This is where the JavaScript setFilterXml() API becomes a life-saver. In this article, I’ll show you how to filter a subgrid dynamically using JavaScript — even when the subgrid’s entity is completely unrelated to the main form entity.

Use Case

Imagine your form has a field called Name, and you want to filter the subgrid so that it shows only records whose Name begins with the same prefix.

But:

  • a. The entities aren’t related.
  • b. The field isn’t in the view.
  • c. And the filtering must be done purely based on the form’s context.

As there are also records, where the lookup column might need to be empty on purpose, which further would break relationship based filtering in the subgrid.

OOB? Impossible.

With JavaScript? Totally doable.

How the JS based subgrid filtering works

In Dynamics 365, subgrids are rendered as independent UI components inside the form. Even though the form loads first, subgrids load asynchronously in the background, which means:

The form and its fields may already be available, but the subgrid control might not yet exist, so trying to apply a filter immediately on form load will fail.

Here is the basic structure of a JS Function to perform Subgrid filtering –


This control represents the interactive UI component that displays the records for the view.
It gives you programmatic access to:
-> Set filters
-> Refresh the grid
-> Access its view ID
-> Handle events (in some versions)

However, because subgrids load later than the form, this line may return null the first several times. If you proceed at that point, your script will break.
So we implement a retry pattern:

If the subgrid is not ready, wait 100ms -> Try again -> Repeat until the control becomes available

This guarantees that our next steps run only when the subgrid is fully loaded.

var oAnnualTCVTargetGridFilter = oAnnualTCVTargetGridFilter || {};

oAnnualTCVTargetGridFilter.filterSubgrid = function(executionContext) {
var formContext = executionContext.getFormContext();

function applyFilter() {
    var subgrid = formContext.getControl("tcvtargets");
    if (!subgrid) {
        setTimeout(applyFilter, 100);
        return;
    }

    var cfAttr = formContext.getAttribute("cf_name");
    var cfName = cfAttr ? cfAttr.getValue() : null;

    if (!cfName || cfName.length < 6) {
        var emptyFilter =
            "<filter type='and'>" +
                "<condition attribute='cf_name' operator='eq' value='__none__' />" +
            "</filter>";

        subgrid.setFilterXml(emptyFilter);
        subgrid.refresh();
        return;
    }

    var prefix = cfName.substring(0, 6);
    var filterXml =
        "<filter type='and'>" +
            "<condition attribute='cf_name' operator='like' value='" + prefix + "%' />" +
        "</filter>";

    subgrid.setFilterXml(filterXml);
    subgrid.refresh();
}

setTimeout(applyFilter, 100);

};

To make sure the filter is applied correctly, we follow a three-step workflow:

1. Retry Until the Subgrid Control Is Loaded (setTimeout)

When the script runs, we attempt to retrieve the subgrid control using:

var subgrid = formContext.getControl("tcvtargets");

2. Apply the Filter (setFilterXml())

Once the subgrid control is found, we can safely apply a filter.

Then we can apply our filtering logic, and utilize it in the FetchXML Query:

-> Read the field Name (cf_name) from the main form & design a logic

-> Construct a FetchXML <filter> element

-> Passing this XML to the subgrid using:

subgrid.setFilterXml(filterXml);

This tells Dynamics 365 to apply an additional filter on top of the existing view used by the subgrid.

A few important things to note:

  • a. We cannot replace the entire FetchXML of the view
  • b. We can only inject the filter portion
  • c. The field being filtered does not need to necessarily exist in the subgrid view
  • d.The entities do not need a relationship

If the cf_name field is empty, we instead apply a special filter that returns no rows.

This ensures the grid displays only relevant and context-driven data.

3. Refresh the Subgrid (subgrid.refresh()) –

After applying the filter XML, the subgrid must be refreshed:

subgrid.refresh();

Without this call, Dynamics will not re-run the query, meaning your filter won’t take effect until the user manually refreshes the subgrid.

Refreshing forces the system to:

-> Re-query data using the combined view FetchXML + your custom filter

-> Re-render the grid

-> Display the filtered results immediately

This gives the user a seamless, dynamic experience where the subgrid shows exactly the records that match the context.

JS + FetchXML based filtering in action –

Without filtering :-

With filtering :-

Key Advantages of This Approach

Works Even When No Relationship Exists

Possibility to filter a subgrid even if the target entity has no direct link to the form’s main entity. This is extremely useful in cases where the relationship must remain optional or intentionally unpopulated.

Enables Dynamic, Contextual Filtering

We can design filtering logic on the form field values, user selections, or business rules.

Filtering on Fields Not Included in the View

Since the filtering logic is applied client-side, there is no need to modify or clone the system view just to include filterable fields.

Bypasses Limitations of Lookup-Based Relation Filtering

This method works even when the lookup column is intentionally left empty, which is a scenario where OOB relationship-based filtering fails.

More Flexible Than Traditional View Editing

You can apply advanced logic such as prefix matching, conditional filters, or dynamic ranges—things not possible using standard UI-only configuration.

To conclude, filtering subgrids dynamically in Dynamics 365 is not something the platform supports out-of-the-box- especially when the entities are unrelated or when the filter criteria doesn’t exist in the subgrid’s original view. However, with a small amount of JavaScript and the setFilterXml() API, you gain complete control over what data appears inside a sub grid, purely based on the context passed from the main form.

I Hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudFronts.com.


Share Story :

SEARCH BLOGS :

FOLLOW CLOUDFRONTS BLOG :


Secured By miniOrange