Recursive calls to hide standard form controls in Microsoft D365 Finance and Operations

Recursive calls to hide standard form controls in Microsoft D365 Finance and Operations

Many times, you would come across a situation when a client asks to use standard form and show only necessary controls.

You can hide controls by using element.design().controlname("").visible(false);

However, you will face problems when new controls are added to the same form either through customizations or Microsoft platform updates. In this case, the client again requests the developer to hide controls when they see a new control. This problem can be solved by showing only selective controls and hiding others automatically by looping FormBuild controls and hiding them.

Let's take CustInvoiceJournal for example.

No alt text provided for this image

Say, You want to show only 6 important columns in the grid here and nothing else.

Please note, all controls will be hidden using this approach.

Standard buttons like Edit, Save, Options, PowerApps, Attachments, refresh, Open in a new window, and close will also hide unless you mention them explicitly.

No alt text provided for this image

Step 1: Observe controls hierarchy

Observe the Hierarchy in form designer for CustInvoiceJournal

No alt text provided for this image

Note that ActionPane, NavigationList, PanelTab are "containers"

Any control which holds another control is treated as a container in D365!

So if I loop through Action Pane, I would infer

No alt text provided for this image
  • Button Groups will be child controls.
  • Also, these button groups are also containers
  • So I loop through another child say Invoice > Accounting Group

We get AccountingDistributionsDocumentView which is NOT a container and can be hidden directly.

The image on RHS is just to understand what is a container and what is not.

Step 2: Create a form event handler, copy the "activated" event handler and use the below code

class ISR_CustInvoiceJournalFormEventHandler
{
    [FormEventHandler(formStr(CustInvoiceJournal), FormEventType::Activated)]
    public static void CustInvoiceJournal_OnActivated(xFormRun sender, FormEventArgs e)
    {
        FormBuildControl formBuildControl;
        int i,j;
        ;


        for (i=1; i <= sender.form().design().controlCount(); i++)
        {
            formBuildControl = sender.form().design().controlNum(i);


            if (formBuildControl.isContainer())
            {
                switch (formBuildControl.name())
                {
                    case    "ActionPane",
                            "PanelTab":
                                ISR_CustInvoiceJournalFormEventHandler::hideParentChildFormControls(formBuildControl, sender);
                        break;
                    default:
                        break;
                }
            }
        }
    }


    private static void hideParentChildFormControls(FormBuildControl _formBuildControl, xFormRun sender)
    {
        FormBuildControl childBuildControl;
        int j;
        ;
        for (j=1; j <= _formBuildControl.controlCount(); j++)
        {
            childBuildControl = _formBuildControl.controlNum(j);
            switch(childBuildControl.name())
            {
                // show standard buttons
                case    "SystemDefinedShowFiltersButton",
                        "SystemDefinedFilterPane",
                        "SystemDefinedManageViewFilters",
                        "PrioritizedPage",
                        "SystemDefinedOptions",
                        "SystemDefinedButtonsButtonGroup_Form",
                        "SystemDefinedFilterManager":
                            sender.design().control(childBuildControl.id()).visible(true);
                    break;


                case    "CustomFilterGroup":
                            sender.design().control(childBuildControl.id()).visible(true);
                    break;


                // show these grid columns only
                case    formControlStr(CustInvoiceJournal, CustInvoiceJour_InvoiceNum_Grid),
                        formControlStr(CustInvoiceJournal, CustInvoiceJour_InvoiceAccount_Grid),
                        formControlStr(CustInvoiceJournal, CustomerName),
                        formControlStr(CustInvoiceJournal, CustInvoiceJour_SalesOrderNumber_Grid),
                        formControlStr(CustInvoiceJournal, CustInvoiceJour_InvoiceDate_Grid),
                        formControlStr(CustInvoiceJournal, CustInvoiceJour_InvoiceAmount_Grid):
                            sender.design().control(childBuildControl.id()).visible(true);
                    break;


                // recursive call
                case    formControlStr(CustInvoiceJournal, GridTab),
                        formControlStr(CustInvoiceJournal, MainGrid):
                            ISR_CustInvoiceJournalFormEventHandler::hideParentChildFormControls(childBuildControl, sender);
                    break;


                default:
                            sender.design().control(childBuildControl.id()).visible(false);
                    break;
            }
        }
    }


}
No alt text provided for this image

Voila, As you can see here, the form has only those controls we want to see.

Further addition of controls will not impact the view of this form.

I recommend this approach only for the below cases

  • The developer cannot duplicate standard form as it is complicated
  • The standard form has references that cannot be replicated
  • One must conditionally hide controls on the form event handler. Without this condition, the standard form should appear as it is.

To view or add a comment, sign in

More articles by Israr Ahmed Khan

Others also viewed

Explore content categories