I was presented with a task to run a workflow via jQuery. I know that SPServices has this capability, but I have never tried it before being assigned this task. So I set out and found some good references. After creating the link in XSL and the jQuery script, the workflow is not starting and SPServices is returning an error since the responseXML is undefined.
XSL code which passes parameters and calls js function
<a href="#">
<xsl:attribute name="onclick">
<xsl:text>javascript:StartWorkflow('</xsl:text>
<xsl:value-of select="@EncodedAbsUrl" disable-output-escaping="yes"/>
<xsl:text>','</xsl:text>
<xsl:value-of select="@ID" disable-output-escaping="yes"/>
<xsl:text>','myListName','emailTest');</xsl:text>
</xsl:attribute>
Email Me</a>
The parameters passed to StartWorkflow function are the Encoded URL of the list item, the ID of the item, the list in which the item resides and the name of the workflow I want to run, respectively. I can verify that the workflow is grabbing the parameters as string objects.
Javascript functions that should process the workflow
function StartWorkflow(ItemURL, ItemID, ListName, DesiredWorkflow) {
var id = "";
$().SPServices({
operation: "GetList",
listName: "myListName",
async: false,
completefunc: function (xData, Status) {
id = $(xData.responseXML).find("List").attr("ID").toString();
}
});
//Get list Id from current page
if (id) {
this.guid = new SP.Guid(id);
var context = SP.ClientContext.get_current();
var lists = context.get_web().get_lists();
var list = lists.getById(this.guid);
//Set workflows variable to load and be accessible in callbacks
this.workflows = list.get_workflowAssociations();
context.load(this.workflows);
context.executeQueryAsync(Function.createDelegate(this, onQuerySucceeded), Function.createDelegate(this, onQueryFailed));
}
function onQuerySucceeded(sender, args) {
var enumerator = this.workflows.getEnumerator();
while (enumerator.moveNext()) {
var workflow = enumerator.get_current();
if (workflow.get_enabled() && workflow.get_allowManual()) {
var workflowName = workflow.get_name();
if (workflowName == DesiredWorkflow){
var workflowGuid = '{' + workflow.get_id().toString() + '}';
//alert(workflowName + " ..... " + workflowGuid);
RunWorkflow(ItemURL, ItemID, workflowGuid);
}
}
}
}
function onQueryFailed(sender, args) {
alert('Unable to retrieve workflows: ' + args.get_message());
}
}
function RunWorkflow(ItemURL, ItemID, workflowGuid) {
var loadingImage = 'Loader' + ItemID;
var workflowDiv = 'WorkflowDiv' + ItemID;
var workflowParams = "<root />";
//Show our loading image
document.getElementById(loadingImage).style.visibility = 'visible';
$().SPServices({
operation: "StartWorkflow",
async:true,
item: ItemURL,
templateId: workflowGuid,
workflowParameters: workflowParams,
completefunc: function (xData, Status) {
if(Status != "error"){
document.getElementById(workflowDiv).innerHTML = 'Item emailed';
}
else{
document.getElementById(workflowDiv).innerHTML = '<div style=\"color:#FF0000\">Error</div>';
if (xData.responseXML != undefined)
window.alert(xData.responseXML.text);
else
window.alert("Error. call assistance, probably the workflow was changed and has another GUID."); }
}
});
}
I ran Fiddler to see if I could find where issues are starting. Fiddler is returning a 404 error when the StartWorkflow SPServices call runs. The SPServices GetList call works fine as long as I do not pass a parameter for listName (I have to type out list name, which is annoying since it adds a few more steps in making the script reusable.
The script is running through the end of the completefunc in the StartWorkflow SPServices call but then has a "Status" = "Error" and the responseXML is undefined. This results in a workflow not running via jQuery. Any advice on where the issue may be starting would be greatly apprecited.