A few projects I’ve worked on required the need to start a workflow programatically using JavaScript, this is achieved by having the user click a link somewhere (such as in an e-mail) which takes them to a page where the magic happens.

This works by parsing some parameters within the URL that is sent to the page, the JavaScript then extracts these parameters and uses them to build the query needed to start the relevant workflow.

One very useful tool at our disposal is the ability to start Workflows via JavaScript with the use of JQuery (you can replace the JQuery parts to make it full JavaScript if required)

This is great for creating custom actions or approval stages which need to be triggered by something like a link in an e-mail or a link on a list item to then start a workflow programatically using JavaScript

Note: this demo uses FontAwesome (click here to download) to display the spinning loading icon below the “Please wait” text

Example images
Landing page:

Thank you message (successful):

Error message (failed):

To set this up first create a page somewhere (this can be in the top tenancy site collection and used on all other sites in the site collection) and then open it up in Edit mode

Add a new Script webpart and paste in the following code:

<link rel="stylesheet" href="/SiteAssets/font-awesome.min.css">
<div style="font-family: segoeui,Arial,Helvetica,sans-serif;font-weight: 500;line-height: 1.1;text-align: left; color: #43AFFF;font-size: 40px;margin-top: 5px;margin-bottom: 5px;">
<div id="msg" style="text-align: center;">Please wait.....
<i id="icon2" style="font-size:84px">


Create a new JavaScript file and save it somewhere inside your site collection then paste the following code into the file:


<script src=”/_layouts/15/sp.workflowservices.js”></script> <script src=”/_layouts/15/SP.Runtime.js”></script> <script> SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’,init); function init() { $.getScript(SP.Utilities.Utility.getLayoutsPageUrl(‘sp.js’), function () { $.getScript(SP.Utilities.Utility.getLayoutsPageUrl(‘sp.workflowservices.js’), function () { getDetails(); }); }); } //dialog element to show during processing var dlg = null; //Subscription id – Workflow subscription id //list item id for which to start workflow. If site workflow, then send null for itemId //SiteURL – site collection where the workflow exists function StartWorkflow(subscriptionId, itemId, SiteURL) { showInProgressDialog(); var ctx = new SP.ClientContext(SiteURL); var wfManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var subscription = wfManager.getWorkflowSubscriptionService().getSubscription(subscriptionId); ctx.load(subscription, ‘PropertyDefinitions’); ctx.executeQueryAsync( function (sender, args) { var params= new Object(); //Find initiation data to be passed to workflow. var formData = subscription.get_propertyDefinitions()[“FormData”]; if (formData != null &amp;&amp; formData != ‘undefined’ &amp;&amp; formData != “”) { var assocParams = formData.split(“;#”); for (var i = 0; i < assocParams.length; i++) { params[assocParams[i]] = subscription.get_propertyDefinitions()[assocParams[i]]; } } if (itemId) { wfManager.getWorkflowInstanceService().startWorkflowOnListItem(subscription, itemId, params); } else { wfManager.getWorkflowInstanceService().startWorkflow(subscription, params); } ctx.executeQueryAsync( function (sender, args) { closeInProgressDialog(SiteURL); }, function (sender, args) { closeInProgressDialog(SiteURL); $(‘#msg’)[0].innerHTML = “Woops – something went wrong, the document may have already been reviewed”; } ); }, function (sender, args) { closeInProgressDialog(SiteURL); $(‘#msg’)[0].innerHTML = “Woops – something went wrong, the document may have already been reviewed”; } ); }
function closeInProgressDialog(SiteURL) { if (dlg != null) { dlg.close(); $(‘#msg’)[0].innerHTML = “Thank you – you can now close the page”; } } function showInProgressDialog() { if (dlg == null) { dlg = SP.UI.ModalDialog.showWaitScreenWithNoClose(“Please wait…”, “Waiting for workflow…”, null, null); } } function getDetails(){ if ((document.URL.indexOf(‘?’)==-1)||(document.URL.indexOf(‘&amp;’)==-1)) { $(‘#msg’)[0].innerHTML = “Woops – something went wrong, it looks the worfklow ID or item id are not correct”; } else{ var params = document.URL.split(“?”)[1].split(“&amp;”); var ListID; var ItemID; var WorkflowID; var SiteURL; // Extracts the property values from the query string. for (var i = 0; i < params.length; i = i + 1) { var param = params[i].split(“=”); if (param[0] == “WorkflowID”) WorkflowID = decodeURIComponent(param[1]); else if (param[0] == “ListID”) ListID = decodeURIComponent(param[1]); else if (param[0] == “SiteURL”) SiteURL = decodeURIComponent(param[1]); else if (param[0] == “ItemID”) ItemID = decodeURIComponent(param[1]);} if (WorkflowID == null){console.log(“No workflow ID provided”);} else{ console.log(WorkflowID); console.log(ItemID); StartWorkflow(WorkflowID,ItemID,SiteURL);} } }; </script>


Add a new editor webpart somewhere on the page and set the File Link property in the Content Editor properties screen to the location of the file

you just created in the previous step (this will ensure the file gets loaded when the page is opened)

Press OK to save the changes to the webpart






That’s it! You can now fire off any workflows by following the format listed below

https://tenancy.sharepoint.com/Pages/Document-Approvals.aspx?WorkflowID=78DA0047-070F-44F6-8D67-15FB8D537BCA&ItemID=3&SiteURL=https://tenancy.sharepoint.com/teams/ICT >


Remember to replace the following bits:

Change from Change to
https://tenancy.sharepoint.com/Pages/Document-Approvals.aspx URL to the page you created in step 1
WorkflowID=78DA0047-070F-44F6-8D67-15FB8D537BCA Change to the Subscription ID of the Workflow you want to call
&ItemID=3& ID of the item in the list you want the Workflow to run on – leave blank to run without an ID
&SiteURL=https://tenancy.sharepoint.com/teams/ICT the URL of the site the workflow currently lives in

Why not take a look at using a similar approach to Create a voting system by e-mail using this same functionality in SharePoint