Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics 365 | Integration, Dataverse...
Suggested answer

Filtering on N:N subgrid

(0) ShareShare
ReportReport
Posted on by 5

Hi,

I am having issues filtering with linked entity XML with the below code on a N:N subgrid:

The issue is coming from the 'filterXml', I am able to filter this fine without using the 'link-entity' but I need to filter by this, is it possible to use the link-entity or adjust the code to support the link-entity?

// Custom function to call instead of the OOTB Add Existing button/command - all 3 parameters can be passed as CRM Parameters from the ribbon
FilterAddExistingVendor: (selectedEntityTypeName, selectedControl, firstPrimaryItemId) => {
console.log('here');
if (selectedControl.getRelationship().name == "XYZ_bookableresource_msdyn_vendor") {
// Custom Account -> Contact N:N - filters to show only contacts with this account as the parentcustomerid
var options = {
allowMultiSelect: true,
defaultEntityType: "msdyn_vendor",
entityTypes: ["msdyn_vendor"],
disableMru: true,
showNew: true,
searchText: "\n", // Search by default
filters: [{
entityLogicalName: "msdyn_vendor",
filterXml: //"<filter type='and'><condition attribute='msdyn_vendoraccountnumber' operator='eq' value='" + 'TEST' + "' /></filter>" +
"<link-entity name='msdyn_vendorgroup' from='msdyn_vendorgroupid' to='msdyn_vendorgroupid' link-type='inner' alias='ag'>" +
"<filter type='and'><condition attribute='msdyn_vendorgroup' operator='eq' value='" + 'SUBCON' + "' /></filter>"
}]
};

XYZ.BookableResource.lookupAddExistingRecords("XYZ_bookableresource_msdyn_vendor","bookableresource", "msdyn_vendor", firstPrimaryItemId, selectedControl, options);
}
else {
// Any other contact relationship (N:N or 1:N) - use default behaviour
XrmCore.Commands.AddFromSubGrid.addExistingFromSubGridAssociated(selectedEntityTypeName, selectedControl);
}
},

// relationshipName = the schema name of the N:N or 1:N relationship
// primaryEntity = the 1 in the 1:N or the first entity in the N:N - for N:N this is the entity which was used to create the N:N (may need to trial and error this)
// relatedEntity = the N in the 1:N or the secondary entity in the N:N
// parentRecordId = the guid of the record this subgrid/related entity is used on
// gridControl = the grid control parameter passed from the ribbon context
// lookupOptions = options for creating the custom lookup with filters: docs.microsoft.com/.../lookupobjects
lookupAddExistingRecords: (relationshipName, primaryEntity, relatedEntity, parentRecordId, gridControl, lookupOptions) => {
Xrm.Utility.lookupObjects(lookupOptions).then(function (results) {
if (results.length > 0) {
// Get the entitySet name for the primary entity
Xrm.Utility.getEntityMetadata(primaryEntity).then(function (primaryEntityData) {
var primaryEntitySetName = primaryEntityData.EntitySetName;

// Get the entitySet name for the related entity
Xrm.Utility.getEntityMetadata(relatedEntity).then(function (relatedEntityData) {
var relatedEntitySetName = relatedEntityData.EntitySetName;

// Call the associate web api for each result (recursive)
XYZ.BookableResource.associateAddExistingResults(relationshipName, primaryEntitySetName, relatedEntitySetName, relatedEntity, parentRecordId.replace("{", "").replace("}", ""), gridControl, results, 0)
});
});
}
});
},

// Used internally by the above function
associateAddExistingResults: (relationshipName, primaryEntitySetName, relatedEntitySetName, relatedEntity, parentRecordId, gridControl, results, index) => {
var formContext = gridControl.formContext;

if (index >= results.length) {
// Refresh the grid once completed
formContext.ui.setFormNotification("Associated " + index + " record" + (index > 1 ? "s" : ""), "INFO", "associate");
if (gridControl) { gridControl.refresh(); }

// Clear the final notification after 2 seconds
setTimeout(function () {
formContext.ui.clearFormNotification("associate");
}, 2000);

return;
}

formContext.ui.setFormNotification("Associating record " + (index + 1) + " of " + results.length, "INFO", "associate");

var lookupId = results[index].id.replace("{", "").replace("}", "");
var lookupEntity = results[index].entityType || results[index].typename;

var primaryId = parentRecordId;
var relatedId = lookupId;
if (lookupEntity.toLowerCase() != relatedEntity.toLowerCase()) {
// If the related entity is different to the lookup entity flip the primary and related id's
primaryId = lookupId;
relatedId = parentRecordId;
}

var association = { '@odata.id': formContext.context.getClientUrl() + "/api/data/v9.0/" + relatedEntitySetName + "(" + relatedId + ")" };

var req = new XMLHttpRequest();
req.open("POST", formContext.context.getClientUrl() + "/api/data/v9.0/" + primaryEntitySetName + "(" + primaryId + ")/" + relationshipName + "/$ref", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
index++;
if (this.status === 204 || this.status === 1223) {
// Success
// Process the next item in the list
XYZ.BookableResource.associateAddExistingResults(relationshipName, primaryEntitySetName, relatedEntitySetName, relatedEntity, parentRecordId, gridControl, results, index);
}
else {
// Error
var error = JSON.parse(this.response).error.message;
if (error == "A record with matching key values already exists.") {
// Process the next item in the list
XYZ.BookableResource.associateAddExistingResults(relationshipName, primaryEntitySetName, relatedEntitySetName, relatedEntity, parentRecordId, gridControl, results, index);
}
else {
Xrm.Utility.alertDialog(error);
formContext.ui.clearFormNotification("associate");
if (gridControl) { gridControl.refresh(); }
}
}
}
};
req.send(JSON.stringify(association));
}

  • Jacoooobb Profile Picture
    5 on at
    RE: Filtering on N:N subgrid

    Thanks for the suggestions - I did no go ahead with those as I was able to achieve a solution by using a hybrid filter with the combination of view and JS.  

    Using a defaultViewId I was able to use the link entity and the dynamic company value within the additional filter

    let options = {

    allowMultiSelect: true,

    defaultViewId: 'edbc376b-9dd1-ec11-a7b6-012348941d91', // GUID

    defaultEntityType: "msdyn_vendor",

    entityTypes: ["msdyn_vendor"],

    disableMru: true,

    showNew: true,

    searchText: "\n",

    filters: [{

    entityLogicalName: "msdyn_vendor",

    filterXml: `<filter type='and'><condition attribute='msdyn_company' operator='eq' value='${XYZ.BookableResource.Company.id}' /></filter>`

    }]

    };

  • Suggested answer
    Bipin D365 Profile Picture
    28,981 Moderator on at
    RE: Filtering on N:N subgrid

    Hi,

    There is no easy way to use link entity in fetchxml in lookup object. What you can do is to create a rollup field and store the count of vendor group where name is 'SUBCON' and then use this field in your fetch xml as rollupfield >0.

    docs.microsoft.com/.../define-rollup-fields

    This way you don't need link-entity in your fetch xml.

  • Suggested answer
    Nya Profile Picture
    29,060 on at

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Ramesh Kumar – Community Spotlight

We are honored to recognize Ramesh Kumar as our July 2025 Community…

Congratulations to the June Top 10 Community Leaders!

These are the community rock stars!

Announcing the Engage with the Community forum!

This forum is your space to connect, share, and grow!

Leaderboard > Microsoft Dynamics 365 | Integration, Dataverse, and general topics

#1
Adis Profile Picture

Adis 136 Super User 2025 Season 1

#2
Sohail Ahmed Profile Picture

Sohail Ahmed 81

#3
Jonas "Jones" Melgaard Profile Picture

Jonas "Jones" Melgaard 77 Super User 2025 Season 1

Product updates

Dynamics 365 release plans