Firing Workflows using Javascript, I've never had to pass in Initiation Parameters. This post takes a look at how to do just that and provides some code that will allow easy use of Workflows in Javascript.
Setup Workflow
The workflow has to be set for Manual starting, otherwise this will not work. Also, to pass in parameters to the workflow, you'll need to have Initiation Variable(s) within the workflow. I've only fiddled with Number and Single Line of Text fields, so if you use other column types, feel free to share your experience.
![]() |
Workflow Initiation Parameters |
This workflow is simply logging the variables out to the Workflow History. Easy peazy...
Workflow Parameters
Looking over the documentation for SPServices and StartWorkflow, I found some examples that were a great starting point. After fiddling a bit with 1 field, I decided to test this a little more. I created a column with spaces in the Name field *gasp*. I only did this to see how to handle this programmatically, so a word to the wise: Friends don't let friends create columns with spaces...
Reading over the examples, if you have multiple parameters, it says you have to change from passing the column name to this weird pattern:
<Data><Parameter1>" + parameter1 + "</Parameter1><Parameter2>" + parameter2 + "</Parameter2></Data>
I've found this to not work at all for me at all [sad_panda]... Back to the drawing board, I guess. Then an idea came to me. Since I'm targeting a column with a space in it, I tried what normally happens to spaces in Static Names: _x0020_. So, I tried this next:
However, this didn't work either! Very curious to find a resolution, I set out to find out why this didn't work... Using SPD (SharePoint Designer), you are able to view the files generated by the workflow. Opening up the XML file as text, you can clearly see that SPD removed the space in the Static Name.
Within this file, all of the Initiation Parameters are visible and it's now easy to tell what's exactly going on.
For all of this to work while using multiple parameters, you have to use the exact Static Name as defined in the XML. The workflow parameters below work just fine for me now.
<Data><TextField>Will it blend?</TextField><With_x0020_Spaces>42</With_x0020_Spaces
></Data>
However, this didn't work either! Very curious to find a resolution, I set out to find out why this didn't work... Using SPD (SharePoint Designer), you are able to view the files generated by the workflow. Opening up the XML file as text, you can clearly see that SPD removed the space in the Static Name.
![]() |
Workflow wfconfig.xml |
![]() |
Workflow Parameter Names |
<Data><TextField>Will it blend?</TextField><WithSpaces>42</WithSpaces
></Data>
Code to Fire the Workflow
This function will handle the pain of getting a workflow to fire. All you need to know is the correct URL, the workflow name, and the workflow parameters ( if any ).
*** Update ***
I took my original idea and made it more or less a plug-in for SPServices. Add this function to the SPServices source and it'll work without any issues.
Original function:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.fn.SPServices.StartWorkflow = function(options) { | |
var opt = $.extend({}, { | |
itemUrl: null, | |
workflowName: null, | |
workflowParameters: "<root />", | |
completefunc: null, // Function to call on completion of rendering the change. | |
debug: false // If true, show error messages;if false, run silent | |
}, options), | |
thisFunction = "SPServices.StartWorkflow", | |
executeWorkflow = $.Deferred(), | |
templates = null, | |
getTemplatesForItem = "GetTemplatesForItem" | |
; | |
function getTemplates() { | |
return $().SPServices({ | |
operation: getTemplatesForItem, | |
item: opt.itemUrl | |
}); | |
} | |
function startWorkflow(workflowTemplates) { | |
var workflowGUID = null, | |
$workflowTemplates = $(workflowTemplates), | |
startWorkflow = "StartWorkflow", | |
output = {} | |
; | |
output[getTemplatesForItem] = workflowTemplates; | |
$workflowTemplates.find("WorkflowTemplates > WorkflowTemplate").each(function(i,e) { | |
var $this = $(this) | |
; | |
// find workflow name | |
if ($this.attr("Name") === opt.workflowName) { | |
var guid = $this.find("WorkflowTemplateIdSet").attr("TemplateId"); | |
if (guid) { | |
workflowGUID = "{" + guid + "}"; | |
output.workflowGUID = workflowGUID; | |
// Stops jQuery#each iteration | |
return false; | |
} | |
} | |
}); | |
if (workflowGUID) { | |
$().SPServices({ | |
operation: startWorkflow, | |
item: opt.itemUrl, | |
templateId: workflowGUID, | |
workflowParameters: opt.workflowParameters, | |
completefunc: function(data, status) { | |
output[startWorkflow] = data; | |
executeWorkflow.resolve(output); | |
if ($.isFunction(opt.completefunc)) { | |
opt.completefunc(output, status); | |
} | |
} | |
}); | |
} else if (opt.debug) { | |
// create error message | |
var workflowError = workflowTemplates.status === 404 ? | |
"The item's URL was not found." : | |
"Workflow name not found." | |
; | |
errBox(thisFunction, "workflowName: " + opt.workflowName, workflowError); | |
executeWorkflow.reject(output); | |
} else { | |
// workflowGUID not defined or network error occured with the GetTemplatesForItem call. | |
executeWorkflow.reject(output); | |
} | |
} | |
// Fire Workflow | |
// jQuery#always is used here, so we guarantee execution of startWorkflow which resolves/rejects the promise. | |
getTemplates().always(startWorkflow); | |
return executeWorkflow.promise(); | |
}; | |
// Example Usage | |
var linkNavWrkFlow = $().SPServices.StartWorkflow({ | |
debug: true, | |
itemUrl: "http://portal/SPDev/Lists/LinkNav/21_.000", | |
workflowName: "Test Wrkflw Params", | |
workflowParameters: "<Data><TestField>All up in your SharePoints.</TestField></Data>", | |
completefunc: function(data, status) { | |
// console.log("StartWorkflow Op Data: " + data.StartWorkflow.responseText); | |
console.log("Status: " + status); | |
} | |
}); | |
// Chaining example | |
$.when( linkNavWrkFlow ).then( | |
function( linkNavWrkFlowData ) { | |
// console.log("StartWorkflow Op Data: " + linkNavWrkFlowData.StartWorkflow.responseText); | |
}, | |
function( linkNavWrkFlowData ) { | |
// console.log("StartWorkflow Failed Op Data: " + linkNavWrkFlowData.StartWorkflow.responseText); | |
} | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example itemUrl for Document: | |
// http://<site>/<DocLib>/doc7.docx | |
// Example itemUrl for Item: | |
// http://<site>/<customsite>/Lists/<ListName>/<ID>_.000 | |
function fireWorkflow ( itemUrl, workflowName, workflowParams ) { | |
workflowParams = workflowParams || "<root />"; | |
$().SPServices({ | |
operation: "GetTemplatesForItem", | |
item: itemUrl, | |
completefunc: function ( data, status ) { | |
var workflowGUID = "" | |
; | |
$(data.responseXML).find("WorkflowTemplates > WorkflowTemplate").each(function(i,e) { | |
var $this = $( this ) | |
; | |
// hard coded workflow name | |
if ( $this.attr("Name") === workflowName ) { | |
var guid = $this.find("WorkflowTemplateIdSet").attr("TemplateId"); | |
if ( guid ) { | |
workflowGUID = "{" + guid + "}"; | |
} | |
// Stops #each iteration | |
return false; | |
} | |
}); | |
$().SPServices({ | |
operation: "StartWorkflow", | |
item: itemUrl, | |
templateId: workflowGUID, | |
workflowParameters: workflowParams, | |
completefunc: function( data, status ) { | |
// Continue processing after workflow is fired. | |
} | |
}); | |
} | |
}); | |
} | |
fireWorkflow( "http://<site>/Lists/<listName>/<ID>_.000", "Workflow Name", "<Data><TestField>All up in your SharePoints.</TestField></Data>" ); |