Triggering a Workflow from a Ribbon Button

Add Button to Entity Ribbon

Export the entity in question and open up customizations.xml. Add the following within the CustomActions tag…

<CustomAction
  Id="CA_MyFirstButton"
  Location="Mscrm.Form.account.MainTab.Save.Controls._children"
  Sequence="31">
  <CommandUIDefinition>
    <Button
      Id="B_MyFirstButton"
      Command="Mscrm.RunSomeJS"
      LabelText="Button Label"
      ToolTipTitle="Run Test Workflow"
      ToolTipDescription="Runs the test workflow to see if this works"
      TemplateAlias="o1"
      Image16by16="/_imgs/ribbon/tools_16.png"
      Image32by32="/_imgs/ribbon/tools_32.png" />
  </CommandUIDefinition>
</CustomAction>

Location sets which area of the ribbon the button will appear on.
Sequence sets where within that ribbon it will appear.
LabelText sets the text which appears under the icon on the ribbon.
TemplateAlias (who knows!)

Create the click action

Now we need to add the command Mscrm.RunSomeJS within the CommandDefinitions section.

<CommandDefinition
  Id="Mscrm.RunSomeJS">
  <EnableRules>
    <EnableRule Id="Mscrm.Enabled" />
  </EnableRules>
  <DisplayRules>
    <DisplayRule Id="Mscrm.CanWriteAccount" />
  </DisplayRules>
  <Actions>
    <JavaScriptFunction
      FunctionName="TriggerWorkflow"
      Library="$Webresource:isah_test">
      <StringParameter
        Value="{guid of account entity}" />
      <StringParameter
        Value="{7D78531A-23EB-4042-9626-1D80DFC10A8D}" />
    </JavaScriptFunction>
  </Actions>
</CommandDefinition>

EnableRules sets if the button is greyed out on the toolbar (always enabled in this example)
DisplayRules sets if the button appears on the toolbar (if the user can write to the account entity in this example)
FunctionName sets the name of the function to run within the web resource
Library sets the name of the web resource JavaScript library to access
StringParameters
in this case are the guid of the account entity (not used currently) and the guid of the workflow to trigger

JavaScript to Fire the Workflow

function TriggerWorkflow(entityName,workflowGuid) {

  var xx = prompt(Xrm.Page.data.entity.getId(),Xrm.Page.data.entity.getId());

  /*Generate Soap Body.*/
  var soapBody = "<soap:Body>" +
                 "  <Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
                 "    <Request xsi:type=\'ExecuteWorkflowRequest\'>" +
                 "      <EntityId>" + Xrm.Page.data.entity.getId() + "</EntityId>" +
                 "      <WorkflowId>" + workflowGuid + "</WorkflowId>" +
                 "    </Request>" +
                 "  </Execute>" +
                 "</soap:Body>";

  /*Wrap the Soap Body in a soap:Envelope.*/
  var soapXml = "<soap:Envelope " +
                "  xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' " +
                "  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
                "  xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
                GenerateAuthenticationHeader() +
                soapBody +
                "</soap:Envelope>";

  /* Create the XMLHTTP object for the execute method.*/
  var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  xmlhttp.open("POST", "/MSCRMservices/2007/crmservice.asmx", false);
  xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
  xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");

  /* Send the XMLHTTP object. */
  xmlhttp.send(soapXml);

}
Advertisements
Leave a comment

8 Comments

  1. Boutros

     /  July 13, 2011

    Hi,

    Can you also include your xml for the display rule please?

    Reply
    • Mscrm.CanWriteAccount is a built-in DisplayRule although I don’t know where they are configured or listed – I just guessed that one!

      I’d start with this page if you want to define your own DisplayRules.

      Reply
  2. Hi, is it possible trigger the workflow by it’s name?
    ID is not very good, if we deploy to other place, the ID will changed, then we have to change again.

    Reply
    • If you transfer the workflow using a solution, I’m fairly certain it keeps the same GUID between different systems so you should be ok.

      You should be able to retrieve the workflowid using a fetchXML query before running the workflow itself. Something like this:-

      <fetch mapping="logical" count="50" version="1.0">
      <entity name="workflow">
      <attribute name="workflowid" />
      <filter>
      <condition attribute="name" operator="eq" value="Workflow Name" />
      </filter>
      </entity>
      </fetch>

      Reply
  3. Hi Pete,
    very helpful post, but I have a question. I wrote the fetchXML jscript on my library to retrive the workflow id and now I need to pass the return value from the fetchXML to the configuration.xml file. So I tried to write the name of the variable here “” without the quotes but obviously, it does’t work! I tried to write it this way “” but it’s wrong too.

    Can you help on this??

    Thanks

    Reply
  4. Chris

     /  February 26, 2015

    Unless I’m missing something, it looks like the parameter, entityName, is never called within the function. I guess it really isn’t needed. You can include it just so you and see easier what the function is calling. Is that why it is there?

    Also do you have any more information about how to add the button without putting it in an existing section? Can you create your own section? Like your example puts it within the Save section. Just wondering

    Reply
  1. Cross Browser Support For Calling Workflow Via Ribbon Buttons | Neil McDonald's Dynamics CRM Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: