Using Form Context and some code, it is possible to set the Subgrid filter.
This article assumes that you already have some familiarity with Model-Driven Apps and Form customization using code. But don’t worry if you’re not familiar with it, at the end of the article I suggest an Udemy course that will guide you through coding implementation.
Context
In the article “Solution: Asset Management (Built with Model Driven App) | by Jean Paul Dosher | Oct, 2023 | Medium”, I pointed out a concern that I had with the screen “Assets”. When the user accesses an existent record the sub grid in botton of the Form don’t filter the columns Asset ID (ID do Ativo in Portuguese):

Client API
The Client API is a programming interface that empowers Power Platform developers to customize and extend model-driven apps, enabling data manipulation, event handling, implement business logic and integration with other UI components.

In our case, basically we want to read if there is an Asset ID filled in the field “Id do Ativo”, if it has value, turn on the Filter (using that value).
To read columns contain data in the model-driven apps form or grids. Use the formContext.data.entity.attributes
collection or the formContext.getAttribute
shortcut method to access a collection of columns:

formContext.getAttribute(arg).getValue()
The argue (arg) will be the logical name of the Table column, you can get that in the proprieties pane in the Form:

Also (one easy way), you can play a bit with the code and obtain all attributes leaving the arg empty: console.log(formContext.getAttribute());

With this, now we can write the full expression with the method getValue()
:
dataformCOntext.getAttribute("jpd_name").getValue()
This will be use only to “not null” validation. For the later action of filtering, we”ll need to use the GUID of the record -this will be passed to the filter to get the unique value of the record.
To get the GUID of the record the data propriety and his entity hierarchy (see formContext diagram picture) along with the “getId” method:
formContext.data.entity.getId();
With this expression, the response will be something like this: “{EEB65B08-CE5A-EE11–8DF0–6045BD3B2479}”
Subgrid Context
“Grids present data in a tabular format in model-driven apps. Grids can span the entire form or can be one of the items on a form; the latter are called subgrids.”
For Subgrid/Grid handling, firstly you will need to obtain the Control element that stores the Subgrid:
A control represents an HTML element present on the form. Some controls are bound to a specific column, whereas others may represent unbound controls such as an IFRAME, web resource, or a subgrid that has been added to the form.
The control object provides methods to change the presentation or behavior of a control and identify the corresponding column. You access controls using one of the following collections:
formContext.ui.controls
formContext.ui Section.controls
formContext.data.entity Attribute.controls
The formContext.getControl method is a shortcut method to access formContext.ui.controls.get.
For my example: formContext.getControl("Subgrid_new_1")

Moving on; in the Grid Context, the methods used to get and set the Filter (getFetchXml
and setFilterXml)
are not documented in the oficial available docs yet, but you can see it here.
With getFetchXml you can see the structure of the grid to use as base for the Filter:
<fetch version='1.0' mapping='logical'
savedqueryid='79f7e750-6a6b-4b11-b812-67cc6cac844c'
eturntotalrecordcount='true' page='1' count='4' no-lock='false'>
<entity name='jpd_alocacaodeativo'>
<attribute name='jpd_alocacaodeativoid'/>
<attribute name='jpd_name'/>
<order attribute='jpd_name' descending='false'/>
<filter type='and'>
condition attribute='statecode' operator='eq' value='0'/>
</filter>
<attribute name='jpd_colaborador'/>
<attribute name='jpd_datadealocacao'/>
<attribute name='jpd_retornarate'/>
<attribute name='jpd_iddoativo'/>
<link-entity alias='a_e5d2f7baeafd4024b47652d6c13sk11' name='jpd_ativo'
to='jpd_iddoativo' from='jpd_ativoid' link-type='outer' visible='false'>
<attribute name='jpd_nomedoativo'/>
</link-entity>
</entity>
</fetch>
In the example I add to the <filter> the condition attribute: <condition attribute='jpd_iddoativo'operator='eq'value='{currentAssetId}'/>
, set the filter with ˜setFilterXml method:gridContext.setFilterXml(fetchXml);
And, finally, refresh the grid to show modifications applied with formContext.getControl('Subgrid_new_1').refresh()
The code
I didn’t explain all the steps of code, like the variable’s attributions, the if condition, etc. But here it is, the sketch of the code used.
this.formOnLoad = function(executionContext)
{
//obtain the main object
var formContext = executionContext.getFormContext();
//get attribute to see if it is null
jpdName = formContext.getAttribute("jpd_name").getValue();
console.log(jpdName);
if(jpdName !== null){
//get current asset id
currentAssetId = formContext.data.entity.getId();
//grid context and fetch xml
gridContext = formContext.getControl("Subgrid_new_1");
exampleFetch = gridContext.getFetchXml();
//build xml with filtered Asset Id
var fetchXml = "<fetch version='1.0' mapping='logical'
savedqueryid='79f7e750-6a6b-4b11-b812-67cc6cac844c' r
eturntotalrecordcount='true' page='1' count='4' no-lock='false'>" +
"<entity name='jpd_alocacaodeativo'>"+
"<attribute name='jpd_alocacaodeativoid'/>"+
"<attribute name='jpd_name'/>"+
"<order attribute='jpd_name' descending='false'/>"+
"<filter type='and'>"+
"condition attribute='statecode' operator='eq' value='0'/>"+
"<condition attribute='jpd_iddoativo' operator='eq' value="+"'"+
currentAssetId+"'"+
"/>"+
"</filter>"+
"<attribute name='jpd_colaborador'/>"+
"<attribute name='jpd_datadealocacao'/>"+
"<attribute name='jpd_retornarate'/>"+
"<attribute name='jpd_iddoativo'/>"+
"<link-entity alias='a_e5d2f7baeafd4024b33652d6c13sk11'
name='jpd_ativo' to='jpd_iddoativo' from='jpd_ativoid'
link-type='outer' visible='false'>"+
"<attribute name='jpd_nomedoativo'/>"+
"</link-entity>"+
"</entity>"+
"</fetch>";
console.log(fetchXml);
gridContext.setFilterXml(fetchXml);
//refresh grid to show filtered data
formContext.getControl('Subgrid_new_1').refresh();
}
}
Conclusion
Model-driven App is handy if well implemented and designed as a solution, not a tool.
Sometimes some business logic or customizations will only be possible with code (that’s my case for this App), I strongly recommend you to take a deep look at the documentation linked bellow -it’s not so big, and you can focus firstly looking at the main objectives/features.
For the code, I recommend putting some error handling in it. You will notice that in my code there’s some “console.log”, that’s for debugging and understanding propose (you can you the Dev-tools of your browser to see it)
The result:
Now, with the implementation:

Leave a Reply