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.
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));
}
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
Post a Comment