Opening a Specified Related Entity Form with Pre-Populated Parameters in Dynamics 365

 In Dynamics 365 customizations, you may encounter scenarios where you need to open a related entity form with pre-populated fields. This is common when you want to create a record in a related entity and carry over some data from the current record. In this article, we will walk through two JavaScript functions that help you achieve this by:

  1. Retrieving the ObjectTypeCode for a given entity using the supported Xrm.Utility.getEntityMetadata method.
  2. Opening the related entity form with parameters and a specific form name by fetching the corresponding formid from the systemform entity.

1. Retrieving the ObjectTypeCode

Each entity in Dynamics 365 is assigned a unique numerical identifier known as the ObjectTypeCode. The following function, GetEntityObjectTypeCode, uses Xrm.Utility.getEntityMetadata to retrieve this code based on the entity's logical name.


/**
 * Retrieves the object type code for a given entity logical name using Xrm.Utility.getEntityMetadata.
 *
 * @param {string} entityLogicalName - The logical name of the entity.
 * @param {function} successCallback - Callback function receiving the object type code.
 * @param {function} errorCallback - Callback function receiving error details.
 * @returns {void}
 *
 * Usage:
 * GetEntityObjectTypeCode("account", function(code) {
 *     console.log("ObjectTypeCode:", code);
 * }, function(error) {
 *     console.error("Error:", error);
 * });
 */
function GetEntityObjectTypeCode(entityLogicalName, successCallback, errorCallback)
{
    if (Xrm.Utility && typeof Xrm.Utility.getEntityMetadata === "function")
    {
        Xrm.Utility.getEntityMetadata(entityLogicalName, ["ObjectTypeCode"]).then(
        function (metadata)
        {
            successCallback(metadata.ObjectTypeCode);
        },
        function (error)
        {
            errorCallback(error);
        });
    }
    else
    {
        errorCallback("Xrm.Utility.getEntityMetadata is not available.");
    }
}


How It Works

  • Function Check: The function first verifies that Xrm.Utility.getEntityMetadata is available. This ensures compatibility with Dynamics 365 Online (v9+).
  • Metadata Retrieval: If available, the function retrieves the metadata for the specified entity, specifically the ObjectTypeCode attribute.
  • Callbacks:
    • On success, the successCallback returns the ObjectTypeCode.
    • On failure, the errorCallback returns an error message.

2. Opening the Related Entity Form with Pre-Populated Parameters

The second function, OpenSpecifiedRelatedEntityFormWithPrePopulation, opens a specified related entity form while pre-populating it with parameters. It uses the previously retrieved ObjectTypeCode to locate the correct system form based on the display name (form name).


/**
 * Opens a specified related entity form with pre-populated parameters.
 * Retrieves the formId by using the provided form name and entity object type code.
 *
 * @param {string} relatedEntityName - Logical name of the related entity.
 * @param {object} primaryControl - The form context of the primary entity.
 * @param {string} parametersString - JSON string representing pre-population parameters.
 * @param {string} formName - Display name of the form to open.
 * @returns {void}
 *
 * Usage:
 * OpenSpecifiedRelatedEntityFormWithPrePopulation("new_relatedentity", formContext, '{"tri_relationshiptype": [434830005]}', "Information");
 */
function OpenSpecifiedRelatedEntityFormWithPrePopulation(relatedEntityName, primaryControl, parametersString, formName)
{
    var parameters = {};
    try
    {
        // Convert parameters string to an object.
        parameters = JSON.parse(parametersString);
    }
    catch (e)
    {
        console.error("Error parsing parameters:", e);
        return;
    }

    var nameValue = "";
    var nameAttribute = primaryControl.getAttribute("name");
    if (nameAttribute !== null && nameAttribute.getValue() !== null)
    {
        nameValue = nameAttribute.getValue();
    }

    var entityFormOptions = {
        entityName: relatedEntityName,
        createFromEntity: {
            entityType: primaryControl.data.entity.getEntityName(),
            id: primaryControl.data.entity.getId(),
            name: nameValue
        },
        openInNewWindow: true
    };

    if (formName !== null && formName !== "")
    {
        GetEntityObjectTypeCode(relatedEntityName,
        function (objectTypeCode)
        {
            // Build FetchXML to retrieve the systemform using objecttypecode and form name.
            var fetchXml = "<fetch top='1'><entity name='systemform'><attribute name='formid' /><filter type='and'>" +
                           "<condition attribute='objecttypecode' operator='eq' value='" + objectTypeCode + "' />" +
                           "<condition attribute='name' operator='eq' value='" + formName + "' />" +
                           "</filter></entity></fetch>";
            Xrm.WebApi.retrieveMultipleRecords("systemform", "?fetchXml=" + encodeURIComponent(fetchXml)).then(
            function (result)
            {
                if (result.entities.length > 0)
                {
                    entityFormOptions.formId = result.entities[0].formid;
                    Xrm.Navigation.openForm(entityFormOptions, parameters).then(
                    function (success)
                    {
                        console.log("Specified related entity form opened successfully.");
                    },
                    function (error)
                    {
                        console.error("Error opening specified related entity form:", error);
                    });
                }
                else
                {
                    console.error("No form found with the specified name: " + formName);
                }
            },
            function (error)
            {
                console.error("Error retrieving formId for form name: " + formName, error);
            });
        },
        function (error)
        {
            console.error("Error retrieving object type code for entity: " + relatedEntityName, error);
        });
    }
    else
    {
        Xrm.Navigation.openForm(entityFormOptions, parameters).then(
        function (success)
        {
            console.log("Related entity form opened successfully.");
        },
        function (error)
        {
            console.error("Error opening related entity form:", error);
        });
    }
}


How It Works

  1. Parameter Parsing:
    The function starts by converting the incoming JSON string (parametersString) into an object. Any parsing errors are logged, and the function exits if the JSON is invalid.

  2. Primary Entity Data Retrieval:
    It retrieves the name attribute from the primary form context (if available) to use as part of the createFromEntity data when creating the new record.

  3. Setting Form Options:
    The entityFormOptions object is configured with the following:

    • The logical name of the related entity.
    • Information about the primary entity (entity type, ID, and name) to link the new record.
    • A flag to open the form in a new window.
  4. Form Identification via FetchXML:
    If a formName is provided, the function calls GetEntityObjectTypeCode to retrieve the entity's ObjectTypeCode. It then builds a FetchXML query to retrieve the corresponding system form based on the form's display name and object type code.

    • If the query finds the form, its formid is assigned to entityFormOptions.formId.
    • The related entity form is then opened with the pre-populated parameters.
  5. Fallback:
    If no formName is provided, the function simply opens the related entity form without specifying a particular form.


Conclusion

By combining metadata retrieval with the capability to open related entity forms, these functions offer a powerful way to extend Dynamics 365's standard functionality. You can pre-populate fields and ensure the correct form is used for data entry, all while maintaining a smooth user experience.

Feel free to adapt and extend these functions to meet your specific business requirements. Happy coding!

No comments:

Post a Comment