Trigger Plugin from Ribbon Button Using Custom Actions in Dynamics CRM 2013

The plugin framework is an extremely powerful feature of CRM where we, as system customizers, can make the CRM do whatever we want.  Before Microsoft Dynamics CRM 2013 came out, we were using out of the box messages like Create, Update, Delete, SetState, Merge, etc. to accomplish a majority of our work.  But what about the times when there is no create, update, delete or any other out of the box event?  Sweat no more!

Custom Actions

Microsoft Dynamics CRM 2013 introduced an exciting feature called Custom Actions. Now we can create our own platform messages and register plugins on them.  These messages can be invoked from JavaScript that in turn can trigger our plugins registered on them.  What’s more is that these custom actions can also have custom input and output parameters. In future blogs, we will show some specifics examples of how we make use of this feature. But for now, here is an example of how we can create a custom action for Order entity that we can invoke from a ribbon button.

–          From the customizations go to Processes

–          Click New, provide value for the Process name, from Category select Action, and from Entity select Order and click OK

You can also specify that this custom action can accept an optional input parameter.  In this case, we are calling it “Data.”  The plugin handling this custom action can read that parameter using PluginContext.InputParameters[“Data”].  If your plugin needs a lot of data passed to it, you can also use XML as value for Data parameter.

–          Save and Activate this process. Activation is a very important step for any process to be used.

Now assuming that we have added a ribbon button to the Order form, we add the below JavaScript to the web resource.  The script creates a simple SOAP envelope to invoke the message, just like you would do for any other out of the box message like Create, Update, Delete, etc.

The first parameter of ExecuteAction is the custom action to be called when the ribbon button is clicked.  The third parameter of ExecuteAction is where we specify the input parameters for our custom action.

function ExecuteAction(requestName, refreshPage, stringParameter)

{

// Creating the request XML for calling the Action

var requestXML = ""

if (stringParameter == null)

{

requestXML += "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">";

requestXML += "  <s:Body>";

requestXML += "

<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services"

xmlns:i="http://www.w3.org/2001/XMLSchema-instance">";

requestXML += "

<request xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">";

requestXML += "        <a:Parameters

xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">";

requestXML += "          <a:KeyValuePairOfstringanyType>";

requestXML += "            <b:key>Target</b:key>";

requestXML += "            <b:value i:type="a:EntityReference">";

requestXML += "              <a:Id>" + Xrm.Page.data.entity.getId() + "</a:Id>";

requestXML += "              <a:LogicalName>" + Xrm.Page.data.entity.getEntityName()

+ "</a:LogicalName>";

requestXML += "              <a:Name i:nil="true" />";

requestXML += "            </b:value>";

requestXML += "          </a:KeyValuePairOfstringanyType>";

requestXML += "        </a:Parameters>";

requestXML += "        <a:RequestId i:nil="true" />";

requestXML += "        <a:RequestName>" + requestName + "</a:RequestName>";

requestXML += "      </request>";

requestXML += "    </Execute>";

requestXML += "  </s:Body>";

requestXML += "</s:Envelope>";

}

else

{

requestXML += "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">";

requestXML += "  <s:Body>";

requestXML += "    <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">";

requestXML += "      <request xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">";

requestXML += "        <a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">";

requestXML += "          <a:KeyValuePairOfstringanyType>";

requestXML += "            <b:key>Target</b:key>";

requestXML += "            <b:value i:type="a:EntityReference">";

requestXML += "              <a:Id>" + Xrm.Page.data.entity.getId() + "</a:Id>";

requestXML += "              <a:LogicalName>" + Xrm.Page.data.entity.getEntityName() + "</a:LogicalName>";

requestXML += "              <a:Name i:nil="true" />";

requestXML += "            </b:value>";

requestXML += "          </a:KeyValuePairOfstringanyType>";

requestXML += "          <a:KeyValuePairOfstringanyType>";

requestXML += "            <b:key>Data</b:key>";

requestXML += "            <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">" + stringParameter + "</b:value>";

requestXML += "          </a:KeyValuePairOfstringanyType>";

requestXML += "        </a:Parameters>";

requestXML += "        <a:RequestId i:nil="true" />";

requestXML += "        <a:RequestName>" + requestName + "</a:RequestName>";

requestXML += "      </request>";

requestXML += "    </Execute>";

requestXML += "  </s:Body>";

requestXML += "</s:Envelope>";

}

var req = new XMLHttpRequest();

req.open("POST", GetServiceUrl(), false)

req.setRequestHeader("Accept", "application/xml, text/xml, */*");

req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");

req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");

req.send(requestXML);

//refresh the page if the request was successful.

if (req.status == 200)

{

if (refreshPage)

{

RefreshForm()

}

}

else

{

Xrm.Utility.alertDialog(req.statusText + "n" + req.responseXML.getElementsByTagName("faultstring")[0].textContent);

}

}

function RefreshForm()

{

Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId());

}

ExecuteAction("new_GenerateOrderReport", true, "");

Now to handle this invocation, we can register a plugin that will be triggered either in pre or post operation just like any other plugin registered on out of the box messages.

Now you have your own messaging framework at your disposal.

For more related information, read Senior Consultant Sudhakar Deenadayalan’s post “MS Dynamics CRM 2013: Generating SSRS Report as PDF Using Plugin.”

Additional Insights

Governance eBook Sample

If you’re using CRM as a platform for deploying line of business applications, make sure you’re getting the most from your investment by reading CRM Governance: What It Is, What It Isn’t, and How to Do It Right, an informative eBook written by governance experts.

Leave a Comment