Setting Columns to Read-Only in an Editable Subgrid in Dynamics 365

  Editable subgrids in Dynamics 365 provide a dynamic way to display and interact with related data directly on a parent form. There are situations, however, where it's necessary to restrict editing of certain fields within these subgrids to maintain data integrity or adhere to business rules. This article explains how to make specific columns in an editable subgrid read-only using JavaScript, employing addOnRecordSelect event depending on the requirement.

Using addOnRecordSelect

The addOnRecordSelect method is used when you need to execute logic based on the interaction with specific rows within a subgrid. This method is triggered whenever a user selects a row, making it suitable for dynamic, row-specific behaviors.

  • Scenario: When your logic needs to dynamically respond to which row in a subgrid is selected and potentially use values from that row to determine behavior, addOnRecordSelect is the go-to method. For instance, disabling specific fields within a row based on the status indicated in that row’s data.
  • Example Use: In a subgrid listing program session attendees, if selecting a row should trigger checks against that row's specific data (like checking the attendee's status to conditionally disable fields only in that row), then addOnRecordSelect is used.

Implementation Steps

  1. Identify the Subgrid and Column: Determine which subgrid and specific column(s) need to be made read-only.

  2. Add JavaScript Web Resource: Create or modify a JavaScript web resource and link it to the form that contains the subgrid.

  3. Register Event Handler: Attach the script to run on the form’s onLoad event, ensuring it triggers when needed.

JavaScript Examples

Using addOnRecordSelect to set specified column of editable subgrid read-only unconditionally


Example: set "emailaddress1" columns read-only in editable subgrid "ContactsSubgrid".

function disableFieldsInSubgridOnRecordSelect(executionContext)
{
    var formContext = executionContext.getFormContext();
    var subgridName = "ContactsSubgrid";
    var fieldNameToDisable = "emailaddress1";

    var subgridControl = formContext.getControl(subgridName);
    if (subgridControl && subgridControl.getGrid)
    {
        subgridControl.getGrid().addOnRecordSelect(function()
        {
            var selectedRow = subgridControl.getGrid().getSelectedRows().get(0);
            var cell = selectedRow.getData().getEntity().attributes.get(fieldNameToDisable);
            if (cell && cell.controls.get(0))
            {
                cell.controls.get(0).setDisabled(true);
            }
        });
    }
}

Using addOnRecordSelect for Conditional Read-Only States

This method is suitable if the read-only state should be applied based on user interaction or specific conditions after a record is selected.

Example: set columns read-only based on a specified column(tri_sessionstatus) value.
Apply to only "In Progress" status.

function disableFieldsInSubgridOnRecordSelect(formContext)
{
    var subgridName = "Subgrid_programsessions";
    var fieldsToDisable = [
        "tri_programsessionproviderid",
        "tri_locationid",
        "tri_externallocation",
        "tri_sessiondate",
        "tri_scheduledstarttime",
        "tri_scheduledendtime",
        "tri_totalparticipants"
    ];

    var subgridControl = formContext.getControl(subgridName);
    if (subgridControl && subgridControl.getGrid)
    {
        subgridControl.getGrid().addOnRecordSelect(function ()
        {
            var selectedRow = subgridControl.getGrid().getSelectedRows().get(0);
            var sessionStatus = selectedRow.getData().getEntity().attributes.get("tri_sessionstatus");

            if (sessionStatus && sessionStatus.getValue() === 434830002) // Status: In Progress
            {
                fieldsToDisable.forEach(function (fieldName)
                {
                    var cell = selectedRow.getData().getEntity().attributes.get(fieldName);
                    if (cell && cell.controls.get(0))
                    {
                        cell.controls.get(0).setDisabled(true);
                    }
                });
            }
        });
    }
}


Registration of above function.
You can register above function at when tab page is expanded, or when subgrid is loaded.

function registerProgramSessionSubgridEventHandler(executionContext)
{
    var formContext = executionContext.getFormContext();
    var tab = formContext.ui.tabs.get("tab_sessions");

    if (tab)
    {
        tab.addTabStateChange(function (tabContext)
        {
            var state = tab.getDisplayState();
            if (state === "expanded")
            {
                disableFieldsInSubgridOnRecordSelect(formContext);
            }
        });
    }
}

or

function registerProgramSessionSubgridEventHandler(executionContext)
{
    var formContext = executionContext.getFormContext();
    var subgridName = "Subgrid_programsessions";

    var subgridControl = formContext.getControl(subgridName);
   
    if (subgridControl)
    {
        subgridControl.addOnLoad(function () {
            disableFieldsInSubgridOnRecordSelect(executionContext);
        });
    }
}


The registerProgramSessionSubgridEventHandler function is invoked in form onLoad event.


Test Result:

Conclusion

By using these methods, you can effectively control the editability of fields within Dynamics 365 editable subgrids. Whether you apply a universal rule with addOnLoad or conditionally adjust fields with addOnRecordSelect, you can ensure compliance with your business rules and maintain data integrity.

No comments:

Post a Comment