11

Let me preface by saying that I'm a relative newbie to this SharePoint stuff and am still fumbling my way around a bit learning from code examples where necessary. That being said, I have no issue starting a workflow using this code, works great.

function startWorkflow(itemID, subID){
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var wfServiceManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
    var subscription = wfServiceManager.getWorkflowSubscriptionService().getSubscription(subID);
    context.load(subscription);
    context.executeQueryAsync(
        function(sender, args){
            console.log("Subscription load success. Attempting to start workflow.");        
            var inputParameters = {};
            wfServiceManager.getWorkflowInstanceService().startWorkflowOnListItem(subscription, itemID, inputParameters);
            context.executeQueryAsync(
                function(sender, args){
                    console.log("Successfully starting workflow.");
                },
                function(sender, args){ 
                    console.log("Failed to start workflow.");
                    console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
                }
            );
        },
        function(sender,args){
            console.log("Failed to load subscription.");
            console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
        }
    );
};

I'm actually trying to terminate then restart a running workflow and I can't for the life of me find an example of how to accomplish this using JSOM. After successful termination I was going to run the above start function to get it going again. This is the code I've started on for terminating a workflow.

function stopWorkflow(listID, itemID){
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var wfServiceManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
    var instanceService = wfServiceManager.getWorkflowInstanceService();
    var wfInstances = instanceService.enumerateInstancesForListItem(listID, itemID);
    context.load(wfInstances);
    context.executeQueryAsync(
        function(sender, args){
            console.log("Instances load success. Attempting to terminate workflow.");
            var e = wfInstances.getEnumerator();
            while(e.moveNext()){
                // Do something here to evaluate if this is the correct instance then
                // something like...
                instanceService.terminateWorkflow(thisInstance);
                context.executeQueryAsync(
                    function(sender, args){
                        console.log("Successfully terminated workflow.");
                    },
                    function(sender, args){
                        console.log("Failed to terminate workflow.");
                        console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
                    }
                );
            }
        },
        function(sender,args){
            console.log("Failed to load instances.");
            console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
        }
    );
};

I'm not sure how to evaluate the enumerated instance properly and get the instance ID to send to the terminateWorkflow function. Any guidance would be greatly appreciated.

Update

So I was finally able to find the available methods for the WorkflowInstance object on DefinitelyTyped. Once I found the methods I was able to use the get_workflowSubscriptionId method to evaluate if the instance was the correct one to terminate. Here's my final functional code for anyone interested.

function terminateWorkflow(listId, itemId, subId){
    var context = SP.ClientContext.get_current();
    var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, context.get_web()); 
    var workflowInstanceService = workflowServicesManager.getWorkflowInstanceService();
    var wfInstances = workflowInstanceService.enumerateInstancesForListItem(listId, itemId);
    context.load(wfInstances);
    context.executeQueryAsync(
        function(sender, args){
            var instancesEnum = wfInstances.getEnumerator();
            while(instancesEnum.moveNext()){
                var instance = instancesEnum.get_current();
                if(instance.get_workflowSubscriptionId().toString() == subId){
                    workflowInstanceService.terminateWorkflow(instance);
                    context.executeQueryAsync(
                        function(sender, args){
                            console.log("Termination Successful");
                        },
                        function(sender,args){
                            console.log("Failed to terminate workflow.");
                            console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
                        }
                    );
                }
            }
        },
        function(sender,args){
            console.log("Failed to load instances.");
            console.log("Error: " + args.get_message() + "\n" + args.get_stackTrace());
        }
    );
};
3
  • I never thought about terminating the workflow. I'll look at adding that to this: gist.github.com/iOnline247/1b3c26f7175296a44274
    – iOnline247
    Mar 25, 2016 at 3:09
  • 2
    Why not put up your solution as the answer?
    – Graham
    Oct 29, 2018 at 16:02
  • 1
    Agree with Graham, instead of being appended to your question, you should post as the answer and accept it so that other searchers see your question as answered in search results.
    – willman
    Feb 18, 2020 at 19:28

1 Answer 1

0

If the list or library that contains the item for which you want to cancel a workflow is not already open, click its name on the Quick Launch. If the name of your list or library does not appear, click View All Site Content, and then click the name of your list or library.

Point to the document or item that is involved in the workflow, click the arrow that appears and then click Workflows.

Under Running Workflows, click the name of the workflow that you want to cancel.

On the Workflow Status page, under Workflow Information, click Terminate this workflow now. If the Terminate this workflow now link does not appear, you do not have the correct permission to perform this task. Contact your administrator if you need to have a workflow canceled.

Regards,

Peter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.