[TIPS] 3 Ways to Filter Subgrid
- View: Edit Filter Criteria
- JavaScript
- Plugin
View: Edit Filter Criteria
- No customization
- Out of the Box feature
JavaScript
- Easier to implement
- For medium complex requirements
Sample Code:
function onLoadFunction(executionContext)
{
var formContext = executionContext.getFormContext(); // get the form context
var tabContext = formContext.ui.tabs.get("tab_Bed_Assignment"); // get the tab context by its name
// Register the event handler for the tab's state change event
tabContext.addTabStateChange(filterSubgridBedAssignments);
filterSubgridBedAssignments(executionContext);
}
function filterSubgridBedAssignments(executionContext)
{
var formContext = executionContext.getFormContext();
var currentBooking = formContext.getAttribute("tri_bookingid").getValue();
var subgrid = formContext.getControl("subgrid_BedAssignments");
//Check if Current Booking Lookup Field is not null
if (currentBooking != null)
{
//Get Lookup Field Id
var currentBookingId = currentBooking[0].id.replace("{", "").replace("}", "");
if (subgrid)
{
//Set Filter XML for Subgrid
var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"
+ "<entity name='tri_bedassignment'>"
+ "<filter type='and'>"
+ "<condition attribute='tri_bookingid' operator='eq' value='" + currentBookingId + "' />"
+ "</filter>"
+ "</entity>"
+ "</fetch>";
subgrid.setFilterXml(fetchXml);
subgrid.refresh();
}
}
else
{
subgrid.setVisible(false);
}
}
Plugin
- For higher complex requirements
Sample Code:
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
public class Filter_MovementsPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace("Filter_MovementsPlugin: Plugin started.");
if (context.InputParameters.Contains("Query") && context.InputParameters["Query"] is FetchExpression fetchExpression)
{
var fetchXmlDoc = XDocument.Parse(fetchExpression.Query);
var entityNode = fetchXmlDoc.Descendants("entity").FirstOrDefault();
var attributeLatestOnly = fetchXmlDoc.Descendants("attribute").FirstOrDefault(attr => attr.Attribute("name")?.Value == "kc_latestonly");
if (attributeLatestOnly == null)
{
tracingService.Trace("Filter_MovementsPlugin: required attribute not found in FetchXML query. Skipping Latest Movement Filter plugin execution.");
return;
}
if (entityNode != null && entityNode.Attribute("name")?.Value == "tri_offendermovement")
{
tracingService.Trace("Filter_MovementsPlugin: tri_offendermovement entity found.");
EntityCollection originalResults = context.OutputParameters["BusinessEntityCollection"] as EntityCollection;
// Filter the original results to include only the latest created records for each subject
var modifiedResults = new EntityCollection();
modifiedResults.EntityName = "tri_offendermovement";
var subjects = originalResults.Entities.Select(e => e.GetAttributeValue<EntityReference>("tri_offenderid")).Distinct();
foreach (var subject in subjects)
{
var subjectId = subject.Id;
// Get the latest created record for each subject from the original results
var latestCreatedEntity = originalResults.Entities
.Where(e => e.GetAttributeValue<EntityReference>("tri_offenderid").Id == subjectId)
.OrderByDescending(e => e.GetAttributeValue<DateTime>("createdon"))
.FirstOrDefault();
if (latestCreatedEntity != null)
{
modifiedResults.Entities.Add(latestCreatedEntity);
}
}
// Set the modified results as the output of the RetrieveMultiple message
context.OutputParameters["BusinessEntityCollection"] = modifiedResults;
}
else
{
tracingService.Trace("Filter_MovementsPlugin: tri_offendermovement entity not found.");
}
}
else
{
tracingService.Trace("Filter_MovementsPlugin: FetchExpression not detected.");
}
tracingService.Trace("Filter_MovementsPlugin: Plugin execution completed.");
}
}
What a great post! Thanks very much for this. Your video walkthrough was easy to understand, and very well explained! I found the plugin option especially interesting. Greetings from Australia :)
ReplyDelete