Run a Dynamics 365 Plugin from JavaScript on Button Click

Trigger a Dynamics 365 Plugin from JavaScript on Button Click

In Dynamics 365, plugins usually run when system events happen — like creating, updating, or deleting a record. But in some cases, you might want to run a plugin only when the user clicks a button on a form.

This blog will guide you step by step on how to trigger a Dynamics 365 plugin from JavaScript using a Custom Action and a Plugin.

Steps to call a plugin from JavaScript

  •  Create a Custom Action
  • Open Advanced Settings → Solutions (or open the specific solution where you want to add the action).
  • Click New in the top menu.
  • Choose Automation → Process.
  • From the process types, pick Action — use an Action when you want to call plugins or custom logic from JavaScript, workflows, or Power Automate.


Once you click on Action a Quick Create Process form will open and fill details.









After that below form is open and you can update process argument as below.


And Activate process.

2. Register the Plugin on the Action

  • Open the Plugin Registration Tool (PRT).
  • Register your plugin step on the Action message.
  • Example: If your Action is named tmx_ReplicateOpportunity, register your plugin on it.

using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

namespace Recreate_Opportunity
{
    public class Recreate : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)
                                     serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory =
                     (IOrganizationServiceFactory)serviceProvider.GetService
                            (typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            try
            {
                // Trigger only when the custom Action is called
                if (context.MessageName == "tmx_ReplicateOpportunity")
                {
                    // Avoid infinite loops
                    if (context.Depth > 1)
                        return;

                    tracingService.Trace("Replicating Opportunity...");

                    // Example: replicate opportunity (pseudo-code, replace with your logic)
                    Guid newOpportunityId = Guid.NewGuid(); 
                    // → here you would actually create a new Opportunity record using service.Create(entity)

                    // Return the new opportunity Id back to the Action as Output Parameter
                    context.OutputParameters["Outputstring"] = newOpportunityId.ToString();
                }
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw new InvalidPluginExecutionException("The following error occurred in Recreate Plugin.", ex);
            }
            catch (Exception ex)
            {
                tracingService.Trace("Recreate Plugin: error: {0}", ex.ToString());
                throw;
            }
        }
    }
}


3. Add JavaScript to Call the Action

function CopyOpportunity(primaryControl) {
        try {
            debugger;
            var guid = Xrm.Page.data.entity.getId();
            //showProgressIndicatior
            Xrm.Utility.showProgressIndicator("Please wait while processing your request");

            //Save current record first once copy button is getting clicked
            primaryControl.data.save().then(function () {
                var recordURL = primaryControl.getUrl();
                var actionName = "tmx_ReplicateOpportunity"; //Replicate Opportunity Outputstring
                executeAction(guid, actionName, primaryControl);
            },
                function () {
                    alert("An Error has occured. Please contact with your System Administrator.");
                });

        } catch (error) {
            Xrm.Utility.closeProgressIndicator();
            alert(error);
            console.log(error);
            throw "An Error has occured. Please contact with your System Administrator.";
        }
    }

    function executeAction(recordURL, actionName, primaryControl) {
        var newopportunityid;
        var recordURL = recordURL.replace(/[{}]/g, '');
        var data = {
            "Inputstring": recordURL,
        };
        var clientURL = Xrm.Page.context.getClientUrl();
        var req = new XMLHttpRequest();

        req.open("POST", clientURL + "/api/data/v8.0/tmx_ReplicateOpportunity", true); //tmx_ReplicateOpportunity
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.onreadystatechange = function () {
        if (this.readyState == 4 /* complete */) {
        req.onreadystatechange = null;
        if (this.status == 200) {
        var receipts = JSON.parse(this.response);
        newopportunityid = receipts.Outputstring;
        
        Xrm.Utility.closeProgressIndicator();
                 var entityFormOptions = {};
                entityFormOptions["entityName"] = "opportunity";
                entityFormOptions["entityId"] = newopportunityid;

    // Open the form.
    Xrm.Navigation.openForm(entityFormOptions).then(
        function (success) {
            console.log(success);
        },
        function (error) {
             console.log(error);
        });
        }
        else {
        var error = JSON.parse(this.response).error;
            Xrm.Utility.closeProgressIndicator();
            alert(error.message)
            console.log(error.message);
        }
        }
        };
        req.send(JSON.stringify(data));
        
    }

4. Add a button to the main form, and set its properties to point to your JavaScript file and function name




Publish and Test

After creating the Custom Action, registering the plugin, and adding the JavaScript:

  • Save the solution.
  • Click Publish All Customizations, so all changes are applied.
  • Open your model-driven app form.
  • Click the custom button you added to the ribbon.
  • The JavaScript will run, call the Custom Action, and trigger the plugin.
  • If everything is set up properly, the functionality should work — for example, a new Opportunity will be created and its Id returned


Thank you

Dharmendra Chavda



















Comments

Popular posts from this blog

Data Upload into CRM from Excel Using Power Automate

Update a Lookup Field value using PowerAutomate