Friday 15 March 2013

Dynamics CRM - Trigger a workflow from JavaScript

 
Updated on – 24th Sep 2015
 
Recently I had a requirement to trigger a workflow on click of ribbon button when it meets certain criteria. Refer below link for calling JavaScript function from custom ribbon button.

http://ankit.inkeysolutions.com/2012/01/crm-2011-how-to-use-visual-ribbon.html

The criteria values are checked using JavaScript and if all criteria are satisfied then the workflow is to be triggered. The function below will take two inputs where entityId is the id of the record for which the workflow will execute and workflowProcessId is the id of the workflow which we want to execute.
function startWorkflow(entityId, workflowProcessId) {
  var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
   "<s:Body>" +
     "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
       "<request i:type=\"b:ExecuteWorkflowRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">" +
         "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">" +
           "<a:KeyValuePairOfstringanyType>" +
             "<c:key>EntityId</c:key>" +
             "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + entityId + "</c:value>" +
           "</a:KeyValuePairOfstringanyType>" +
           "<a:KeyValuePairOfstringanyType>" +
             "<c:key>WorkflowId</c:key>" +
             "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + workflowProcessId + "</c:value>" +
           "</a:KeyValuePairOfstringanyType>" +
         "</a:Parameters>" +
         "<a:RequestId i:nil=\"true\" />" +
         "<a:RequestName>ExecuteWorkflow</a:RequestName>" +
       "</request>" +
     "</Execute>" +
   "</s:Body>" +
 "</s:Envelope>";
 
  var requestURL = Xrm.Page.context.getClientUrl() + "/XRMServices/2011/Organization.svc/web";
  var xmlHttpRequest = new XMLHttpRequest();
  xmlHttpRequest.open("POST", requestURL, false)
  xmlHttpRequest.setRequestHeader("Accept", "application/xml, text/xml, */*");
  xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
  xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
  xmlHttpRequest.send(request);
}


That’s it. The above common method can be used to trigger workflow from JavaScript.

I hope this would be helpful.



24 comments:

  1. is it possible from a home page of an entity ? if i select 10 record in the same time ? does the workflow retrive the 10 GUID of the 10 records ?

    ReplyDelete
  2. No, at present it runs only at record level(via entity form).

    ReplyDelete
  3. will not work on non IE Browsers. (Cross Browser functionality in UR 12) because of the ActiveX call.

    ReplyDelete
  4. Yes, that's true, at present the above function did not support the other browsers.

    ReplyDelete
  5. Hi ankit, how and where we can find that entityid, workflowid.
    Please advice

    ReplyDelete
  6. How and where can we find the entityid and workflowid

    ReplyDelete
  7. Hello Uday,

    On your record window (either entity or workflow) you can click on Copy a Link button. This will allow you to paste the URL of that record in notepad file or any other temporary location. From that URL you could identify the ID (Guid) of that record. I hope it is clear now.

    ReplyDelete
  8. Hello, and thanks for your post. I'm attempting to integrate my workflow GUID and custom entity GUID and wanted to see what I might be doing wrong.

    Should I be adding the GUID like this? (I've removed code reference)

    "EntityId" + "7bBF27441D-AF1F-4E7D-9F72-8C04B9EF5F55" + "/EntityId" +
    "WorkflowId" + "7b1D1F8595-A49F-432C-B1B0-C34ECF2EF55D" + "/WorkflowId" +


    And is that the only place I would input them?

    thanks for your help.

    ReplyDelete
  9. Hello James,

    Yes, you just require to pass the values of these two parameters to startWorkflow Method.

    ReplyDelete
  10. Hi Ankit,
    used the below code, however my workflow isnt firing can you please help?

    function startWorkflow() {
    var entityId = Xrm.Page.data.entity.getId();
    var workflowProcessId = "54698A96-4926-4647-9A12-45DB4C2448B8"; //Workflow Guid.

    var xml = "" +


    "" +


    "" +


    Xrm.Page.context.getAuthenticationHeader() +


    "" +


    "" +


    "" +


    "" + entityId + "" +


    "" + workflowProcessId + "" +


    "" +


    "" +


    "" +


    "";





    var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");


    xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);


    xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");


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


    xmlHttpRequest.setRequestHeader("Content-Length", xml.length);


    xmlHttpRequest.send(xml);


    }

    ReplyDelete
  11. Hi,

    Can you please validate each following point?

    1. Please validate the GUID value of workflow, is that correct?
    2. Is the workflow activated?
    3. Is it On Demand workflow?

    Thanks,
    Ankit


    Thanks,
    Ankit

    ReplyDelete
  12. Replies
    1. Hello Rahul,

      I have updated this post today and it should now work with CRM 2015.

      Delete
  13. Thank you so much man.. Worked like a charm for 2015. :)

    ReplyDelete
  14. Is this JS code still IE-only, or will it now work with Chrome / Firefox, etc.?

    ReplyDelete
  15. Hi,

    It now supports all browsers, it is no more IE-only since 24th Sep 2015.

    Thanks,
    Ankit

    ReplyDelete
  16. Hi,
    i have a requirement that i have to trigger a workflow from ribbon button which is already there. i have used this same code.this is not working. and the button which supposed to do the action that also not happening . can you please guide me.
    Thanks

    ReplyDelete
  17. Hi Work Flow id will change for record to record and while debugging the script showing Guid Undefined

    ReplyDelete
    Replies
    1. Hi,

      You've specified that "The workflow id will change for record to record"

      Can you please elaborate more on that?

      Delete
  18. Hi sir
    i am used same code in java script
    occur some problem "
    Failed to load resource: the server responded with a status of 500 (Internal Server Error)"


    ReplyDelete
  19. Hi Ankit

    Your code works for me well when I fire workflow on same entity. If I try this to fire a workflow on account entity from a contact entity it doesn't work. Can I know why please?

    Thanks
    Arj

    ReplyDelete
    Replies
    1. Hi AJ,

      Sorry for the delayed reply.

      Can you let me know where exactly are you facing the issue? Because the below code works for me for updating the Account by triggering the workflow from Contact. Make sure the workflow is set to trigger On Demand.

      function ContactEmailOnChange(executionContext) {

      //Get the Account Id on Contact
      var formContext = executionContext.getFormContext();
      var accountAttribute = formContext.getAttribute("parentcustomerid");

      if (accountAttribute != null && accountAttribute.getValue() != null) {
      var accountId = accountAttribute.getValue()[0].id;

      var entity = {
      "EntityId": accountId // accountId
      };

      var WorkflowId = "b7f7ebd1-3a91-43a2-8f41-35ed28ee4dfc";

      var req = new XMLHttpRequest();
      req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/workflows(" + WorkflowId + ")/Microsoft.Dynamics.CRM.ExecuteWorkflow", true);
      req.setRequestHeader("OData-MaxVersion", "4.0");
      req.setRequestHeader("OData-Version", "4.0");
      req.setRequestHeader("Accept", "application/json");
      req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
      req.onreadystatechange = function () {
      if (this.readyState === 4) {
      req.onreadystatechange = null;

      if (this.status === 200) {
      Xrm.Utility.alertDialog("Success");
      } else {
      Xrm.Utility.alertDialog(this.statusText);
      }
      }
      };
      req.send(JSON.stringify(entity));
      }
      }

      Delete