Dynamically filter required Fields/Columns from a Record’s BPF and Form and apply Requirement to those fields

Hi Everyone,

Let me explain this topic with an example of a scenario that you might encounter. I’ll walk you through how to complete this scenario in a concise manner below.

Use Case

Let’s say you have a Table (Entity) with or without multiple Business Process Flows (BPFs) that include some required Fields and even on the Form.

Even if the required fields are empty and you want to change a field or flag within the form and save the record.

We must disable all required Fields on the Form and then re-enable the requirements for those fields.

We can do this with some simple JavaScript code.

An Image of Opportunity Record where I’m going to test the JS.

Step 1: Find a trigger point for your JS function to be called.
It can be done with a Ribbon Button or by manually changing a Field.

Find the code you’ll need below. I’ll be using Ribbon Button to trigger my JS Function.

var OpportunityForm = 
{
    formContext: null,
    executeMain: function(primaryControl)
    {
        var formContext = primaryControl;
        if(formContext)
            OpportunityForm.formContext = formContext;

 //get All Fields
        var listofAllFields = formContext.data.entity.attributes.getAll();

 //get All Required Fields in Active BPF
        var findRequiredFieldsInBPF = OpportunityForm.getRequiredFields(formContext);

 //get All Required Fields on the Form
        var requiredFieldsOnForm = [];
        listofAllFields.forEach(element => 
        {
            if(formContext.getControl(element._attributeName) != null)
            {
                if(formContext.getAttribute(element._attributeName).getRequiredLevel() == "required")
                {
                    requiredFieldsOnForm.push(element._attributeName);
                }
            }
        });

        OpportunityForm.markRequirementForFields({argFieldsArray: requiredFieldsOnForm, argRequirementType: "none", argFieldsOn: "onForm"});
        OpportunityForm.markRequirementForFields({argFieldsArray: findRequiredFieldsInBPF, argRequirementType: "none", argFieldsOn: "BPF"});

        //-------------------------------
        // INSERT YOUR CODE HERE TO CHANGE FLAG or ANY DATA
        //-------------------------------


        //Save and Refresh Form and Mark Fields required again
        formContext.data.refresh(true).then(function () 
        {
            OpportunityForm.markRequirementForFields({argFieldsArray: findRequiredFieldsInBPF, argRequirementType: "required", argFieldsOn: "BPF"});
            OpportunityForm.markRequirementForFields({argFieldsArray: requiredFieldsOnForm, argRequirementType: "required", argFieldsOn: "onForm"});

        }, function () 
        { 
            alert("Failed");
            OpportunityForm.markRequirementForFields({argFieldsArray: findRequiredFieldsInBPF, argRequirementType: "required", argFieldsOn: "BPF"});
            OpportunityForm.markRequirementForFields({argFieldsArray: requiredFieldsOnForm, argRequirementType: "required", argFieldsOn: "onForm"});
        });
},
    getRequiredFields: function(formContext)
    {
        var activeProcess = formContext.data.process.getActiveProcess();
        var stageCollection = activeProcess.getStages();
        var FieldsOfAllStagesInBPF = [];
            stageCollection.getAll().forEach(Q => FieldsOfAllStagesInBPF.push(Q.getSteps()) );
        var AllFieldsInBPF = [];
            FieldsOfAllStagesInBPF.forEach(T => AllFieldsInBPF.push(Object.values(T.getAll())));
        AllFieldsInBPF = AllFieldsInBPF.flat();
        var AllFieldsInBPF_logicalName = [];
            AllFieldsInBPF.forEach(Z => AllFieldsInBPF_logicalName.push(Z.getAttribute() ))
        var RequiredFieldsFiltered = [];
            AllFieldsInBPF_logicalName.forEach(S => {
                if(formContext.getControl("header_process_"+S).getAttribute().getRequiredLevel() == "required")
                {
                    RequiredFieldsFiltered.push(S)
                }
            });

        return RequiredFieldsFiltered;
    },
    markRequirementForFields: function({argFieldsArray, argRequirementType, argFieldsOn})
    {
        if(argFieldsOn == "BPF")
        {
            argFieldsArray.forEach(element => 
            {   OpportunityForm.formContext.getControl("header_process_"+element).getAttribute().setRequiredLevel(argRequirementType);
            });
        }
        else if(argFieldsOn == "onForm")
        {
            argFieldsArray.forEach(element => 
            {
                OpportunityForm.formContext.getControl(element).getAttribute().setRequiredLevel(argRequirementType);
            });
        }
    }
}

Quick Tip: You cannot get any Attribute Value of a Field residing in BPF directly. You need to get the entire Control of the Field and then call its attribute values.

Step 2: Register your JS function onto your Ribbon Workbench or OnChange of any Field on Form.

Since I called my function using Ribbon Button, I used “OpportunityForm.executeMain” with Parameters; “CRM Parameter -> Primary Control

If you’re calling the JS using Field OnChange, then register the function as “OpportunityForm.executeMain” and do pass ‘executionContext‘.

In this case, your part of the script will change as below (use this if you use JS on your Form only)

var OpportunityForm = 
{
    formContext: null,
    executeMain: function(executionContext)
    {
        var formContext = executionContext.getFormContext();
         
        ...continue the code...

OUTPUT

This is how all fields will have no requirement on the Form. I took this output before re-enabling the requirement level for the fields.

That’s all, I hope this helped you


Share Story :

Secured By miniOrange