Function

$().SPServices

Web Service

Workflow

Operation

StartWorkflow

Example

This example comes from a great article over at NothingButSharePoint.com by Jason MacKenzie (Intelligence Among Us). In it, Jason shows how you can use a call to StartWorkflow to improve the user experience with, you guessed it, starting a workflow. I'm only going to include the SPServices snippet from the article; read the whole article to see it in context.

Note the trick with the workflowParameters option, where Jason passes an XML node.

<script type="text/javascript" src="/sites/sprc/Resources%20%20jQuery/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/sites/sprc/Resources%20%20jQuery/jQuery%20SP%20Services/jquery.SPServices-0.5.4.min.js"></script>
<script type="text/javascript">

function StartWorkflow(ItemURL, ItemID) {
  var loadingImage = ‘Loader’ + ItemID;
  var workflowDiv = ‘WorkflowDiv’ + ItemID;
  //Show our loading image
  document.getElementById(loadingImage).style.visibility = ‘visible’;
  $().SPServices({
    operation: "StartWorkflow",
    item: ItemURL,
    templateId: "{04ee1c93-f6b7-49b3-a79c-fa3142ecd688}",
    workflowParameters: "<root />",
    completefunc: function() {
      document.getElementById(workflowDiv).innerHTML = ‘Workflow Started’;
    }
  });
}
</script>

Here's another example from Rkbradford in a Discussion thread which shows how you can pass workflow parameter values:

$().SPServices({
  debug:true,
  operation: "StartWorkflow",
  async: true,
  item: "https://server/site/Lists/item" + idData + "_.000",
  templateId: "{c29c1291-a25c-47d7-9345-8fb1de2a1fa3}",
  workflowParameters: "<Data><monthName>" + txtBox.value + "</monthName></Data>",
...


alan_usa provided a tip that, when passing more than one parameter, the syntax should be:

workflowParameters: "<Data><Parameter1>" + parameter1 + "</Parameter1><Parameter2>" + parameter2 + "</Parameter2></Data>"

Last edited Jan 9, 2012 at 2:09 PM by sympmarc, version 6

Comments

iOnline247 Jan 20 at 6:57 PM 
For SharePoint 2013, use the code found here. This will allow triggering of SharePoint 2010 workflows as well, within a SharePoint 2013 environment.

https://gist.github.com/iOnline247/1b3c26f7175296a44274

Cheers,
Matthew

TomBenj Nov 4, 2015 at 9:50 PM 
I notice several of the questions here are to do with the item parameter, and having just worked out how to start a workflow on a document set in a library, I though I'd post what I've learned. At first I was thrown by a 404 error coming back from the call to workflow.asmx, which didn't mean workflow.asmx wasn't accessible, but that the item parameter in the SPServices function was incorrect.

So for a document set I use:
var queryStringVals = $().SPServices.SPGetQueryString();
var rootFolder = queryStringVals["RootFolder"];
var itemUrl = window.location.protocol + "//" + window.location.hostname + rootFolder;

For an item in a list, as others have said, the item parameter is the complete path to the list, e.g. https://server/site/Lists/MyList, followed by the ID of the item in the list and "_.000". How you get the ID of the item depends on the scenario you're working with, but it is the value shown in the ID column of the list.

zer0admin Oct 9, 2015 at 2:10 PM 
I am adding this as an comment on this page because functionality of SPServices.StartWorkflow does not function with SharePoint Foundation 2013 and 2010 Workflows. SharePoint Foundation 2013 does NOT run with Windows Workflow services, and runs with legacy SharePoint 2010 workflow. This comment is intended to help any future users who are hoping to leverage this functionality and saving them countless hours trying to get it to work.

SPServices-2014.02
jquery.v1.11.2.js

Regards,
Zero

yllsuarez Sep 11, 2015 at 10:02 PM 
I tried this in SP2013 without success, I got the "Done" message but the Workflow was not triggered.


var AbsID = getParameterByName('AbsID');
var itemURL = "<site>/Lists/Absences/item" + AbsID + "_.000";



$("#SubmitButton").jqxButton({ width: '150'});

$("#SubmitButton").on('click', function () {
$().SPServices({
operation: "StartWorkflow",
async: true,
item: itemURL,
templateId: "{2e17bef4-9e48-4d00-8cac-398f483077c6}",
workflowParameters: "<Data><Approved?>" + $("#Approved").val() + "</Approved?><Approver Notes>" + $('#Notes').val() + "</Approver Notes></Data>",
completefunc: function() {
alert('Done');
}
});

varindermcp Feb 27, 2015 at 10:05 AM 
HI,

I have SharePoint 2013 online environment and i ma using the below code

var item_id=getParameterByName('ID');
var link="mysiteurl/Lists/VO%20Partners/DispForm.aspx?ID="+item_id;

$().SPServices({
debug:true,
operation: "StartWorkflow",
async: true,
item: "mysiteurl/Lists/VO%20Partners/"+item_id+"_.000",
templateId: "{E7B222C8-B5D5-42B0-B18A-01976F29AB36}",
workflowParameters: "<Data><item_link>[" + link + "]</item_link></Data>"

});


But its throwing NetworkError: 500 Internal Server Error at mysiteurl/_vti_bin/workflow.asmx.

Can anyone help on this

Varinder

avishnyakov Mar 28, 2014 at 6:24 AM 
Time to time, this function seems to trigger "the previous/old" version of the SharePoint Designer workflow.
Any suggestion to troubleshoot that?

AlexChernov Mar 16, 2014 at 11:40 PM 
AymKdn, your code works fine, but it is returning only Sharepoint 2010 Workflows, associated to my list, I see NO 2013 WFs. Any idea how to fix it?

RicardoIrineo Jan 29, 2013 at 9:33 AM 
Just thought I'd share, from the methods in the comments, if you have a reusable workflow, you'll have to retrieve the content types for that list and then get the workflows associated to that content type. Then it'll work great :)

AymKdn Oct 11, 2012 at 4:26 PM 
Here is a function to help with that (code available there too: https://gist.github.com/3873181)

/**
* Start a workflow
*
* @param {Object} params
* @param {String} params.listName The name of the list
* @param {Number} params.itemID The item ID
* @param {Array|Object} [params.parameters] An array of object with {Name:"Name of the parameter", Value:"Value of the parameter"}
* @param {Function} [params.after] Callback after the request is done
*/
function startWorkflow(params) {
// we need to make sure that SP.ClientContext is loaded
if (SP.ClientContext == undefined) {
setTimeout(function() { startWorkflow(params) }, 100);
return
}

params.after = params.after || (function() {});

function onQuerySucceeded() {
var enumerator = workflows.getEnumerator();
while (enumerator.moveNext()) {
var workflow = enumerator.get_current();

if (workflow.get_name() == "Workflow for Requests") {
var url = 'http://' + window.location.hostname + item.get_item("FileRef");
var templateId = '{' + workflow.get_id().toString() + '}';
var workflowParameters = "<root />";
if (params.parameters) {
var p;
if (params.parameters.length == undefined) p = [ params.parameters ];
p = params.parameters.slice(0);
workflowParameters = "<Data>";
for (var i=0; i<p.length; i++)
workflowParameters += "<"+p[i].Name+">"+p[i].Value+"</"+p[i].Name+">";
workflowParameters += "</Data>";
}
// trigger the workflow
jQuery().SPServices({
operation:"StartWorkflow",
async:true,
item:url,
templateId:templateId,
workflowParameters:workflowParameters,
completefunc:params.after
});
break;
}
}
}
function onQueryFailed() { throw "Error with Start workflow" }

//var guid = new SP.Guid(__GlobalConfig.listID['Requested']);
var context = SP.ClientContext.get_current();
var lists = context.get_web().get_lists();
var list = lists.getByTitle(params.listName);
var item = list.getItemById(params.itemID);
var file = item.get_file();

context.load(list);
context.load(item);

var workflows = list.get_workflowAssociations();
context.load(workflows);

context.executeQueryAsync(onQuerySucceeded, onQueryFailed);
}

I'll try to add this feature into my Sharepoint JavaScript API called SharepointPlus (http://aymkdn.github.com/SharepointPlus/)

SPTechQ Jul 13, 2012 at 10:11 PM 
Can you explain what the ITEMURL does ? In the comments by Dan Clements "http://site/subsite/Lists/List Name/ItemID_.000" is that pointing to the complete list or just the first item in the list ?

Thanks

danclements Jun 27, 2012 at 10:19 PM 
ItemURL is http://site/subsite/Lists/List Name/ItemID_.000 for example, http://www.example.com/mySite/Lists/myList/1_.000

sa15 Apr 24, 2012 at 6:42 PM 
We have a activity signup page on our intranet and the "Signup" link is where I want to start the workflow, which basically registers currently logged in user for that activity. I used the above mentioned code from 'nothingbutsharepoint' and that worked too. However when I want to register for multiple activities which are all in the same "Signup" section; it does not work. Meaning the workflow starts/works only for one activity- if I sign up for one activity and want to sign up for anothe one on the same page, it does not do anything??
I am trying to figure out why that is the case. I send the correct ItemID in item url. Anye help would be great.

TimmyGilissen Apr 20, 2012 at 12:20 PM 
Hey,

I have a working example for you guys how to start a workflow on an item in a document library.
Javascript code.

function TriggerTranslateWorkflow(listid) {

if (listid) {

var guid = new SP.Guid(listid);
context = SP.ClientContext.get_current();
var lists = context.get_web().get_lists();
list = lists.getById(guid);
item = list.getItemById(SP.ListOperation.Selection.getSelectedItems()[0].id);
file = item.get_file();

context.load(list);
context.load(item);
context.load(file);

workflows = list.get_workflowAssociations();
context.load(workflows);

context.executeQueryAsync(onQuerySucceeded, onQueryFailed);
}

}

function onQuerySucceeded(sender, args) {
var enumerator = workflows.getEnumerator();
while (enumerator.moveNext()) {
var workflow = enumerator.get_current();

if (workflow.get_name() == "WorkflowName") {
var url = 'http://' + window.location.hostname + file.get_serverRelativeUrl();
var templateId = '{' + workflow.get_id().toString() + '}';

$().SPServices({
operation: "StartWorkflow",
async: true,
item: url,
templateId: templateId,
workflowParameters: "<root />",
completefunc: function () {
alert('Workflow started');
}
});

}
}
}

function onQueryFailed(sender, args) {
alert('Unable to retrieve workflows: ' + args.get_message());
}

Jburnish Apr 17, 2012 at 7:42 PM 
After adding some of the above values, you may have to tweak things to end up with the URL you need.
Some 'Gotcha' moments for me.
Attempting to use <ParameterBinding Name="PageUrl" Location="ServerVariable(URL)" DefaultValue=""/> wouldn't return the full URL outside of my Pages Library.
I ended up having to use.
<ParameterBinding Name="PageUrl" Location="ServerVariable(SERVER_NAME)" DefaultValue=""/>
and
<xsl:value-of select="concat('https://',$PageUrl,@FileRef)" disable-output-escaping="yes" />

The easiest way to validate what you are sending to the web service is to right-click and view source on the web page, then track down your cobbled together javascript. If you are failing to pass the full URL, the workflow will not fire.

You want to see something like this. "https://MyFullPathToMyListOrLibrary/MyItemID_.000"
I haven't tried this with a Document Library, but all Documents are ALSO Items, so it should work.
If it's available to you @EncodedAbsUrl will return the full URL to you (within a ListView)

sympmarc Jan 23, 2012 at 2:57 PM 
StyxOl:

Have you looked at the returned XML? Usually you'll get some indication of the issue. You can intentionally generate an error to see what the messaging might be.

Please post questions like this in the discussions in the future, plese.

M.

StyxOl Jan 20, 2012 at 9:29 PM 
Is there a way to handle the result of web service call? For example if templateId or item url is not correct I do not get any exceptions just nothing happens.

waydej Jan 2, 2012 at 9:16 PM 
I'm having a really hard time figuring out the ItemUrl part. For a list item, what should this be?

mistral61 Sep 19, 2011 at 10:18 PM 
StartWorkFlow is working with a worflow, done with SharePoint Designer 2007, on a Document Library ?
The item link is in the form "https://server/site/Lists/item" + idData + "_.000" ? or is the path of the document ?
the templateID is the BaseID guid in the <wf>xoml.wfconfig.xml ? if i have understood, this guid changes on every change to the wf: can be read via js this guid using the wf name ?
Can be provided a sample ?
Thanks.