質問

I need to add a button on the Display Form of a custom list to start a specific workflow. If I run the code in the Workflows page (from the item click on Workflows which takes you to all available workflows that can be manually started), it works, but from the Display Form I get "Invalid Request" when trying to load WorkflowServiceManager.newObject(context, context.get_web()).

Here is the code:

var context = SP.ClientContext.get_current();
var web = context.get_web();
context.load(web);
context.executeQueryAsync(
    function () {
        console.log('Loaded web..');

        var wfServiceManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
        context.load(wfServiceManager);
        context.executeQueryAsync(
            function () {
                console.log('Successfully loaded wfServiceManager');
                var subscriptionService = wfServiceManager.getWorkflowSubscriptionService();
                context.load(subscriptionService);
                context.executeQueryAsync(
                    function () {
                        var subscription = subscriptionService.getSubscription("202e4b8e-0284-4832-80b4-2d33a66ff549");

                        context.load(subscription);

                        context.executeQueryAsync(
                            function (sender, args) {
                                console.log("Subscription load success. Attempting to start workflow.");
                                var inputParameters = new Object();

                                wfServiceManager.getWorkflowInstanceService().startWorkflowOnListItem(subscription, 1, 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());
                            }
                        );
                    },
                    function (sender, args) {
                        console.log("Error loading subscription service: " + args.get_message() + "\n" + args.get_stackTrace());
                    });

            },
            function (sender, args) {
                console.log('Failed to load wfServiceManager: ' + args.get_message() + args.get_stackTrace());
            }
            );

    },
    function (sender, args) {
        console.log('Failed to load web: ' + args.get_message());
    }
    );

I load sp.workflowservices.js from the form's JSLink. It seems like something is not loaded on the Display Form page.

役に立ちましたか?

解決

I struggled with the SP.WorkflowServices.WorkflowServicesManager as well, trying to do the same thing (start a workflow from a button on the Display form). I don't remember exactly what my problems were, but I ended up resorting to using the REST API and jQuery AJAX:

function getWfSubscriptions() {
    var listID = _spPageContextInfo.pageListId;
    var restUri = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.WorkflowServices.WorkflowSubscriptionService.Current/EnumerateSubscriptionsByList('" + listID + "')";
    $.ajax({
        url: restUri,
        type: 'POST',
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        dataType: 'json',
        success: startWorkflow,
        error: showErrorNotification
    });
}

function startWorkflow(sender, args) {
    var itemID = GetUrlKeyValue('ID');
    for (var i = 0; i < sender.d.results.length; i++) {
        if (sender.d.results[i].Name === "My Workflow Name") {
            var wfSubscription = sender.d.results[i];
            break;
        }
    }
    // my workflow has an initiation parameter called "StartTime"
    var initParams = {
        "payload": [{
            "Key": "StartTime",
            "Value": new Date(),
            "ValueType": "Edm.DateTime"
        }]
    };
    var restUri = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.WorkflowServices.WorkflowInstanceService.Current/StartWorkflowOnListItemBySubscriptionId(subscriptionId='" + wfSubscription.Id + "',itemId='" + itemID + "')";
    $.ajax({
        url: restUri,
        type: 'POST',
        data: JSON.stringify(initParams),
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        dataType: 'json',
        success: workflowStarted,
        error: showErrorNotification
    });
}

他のヒント

Solved it. Problem was that SP.workflowservices.js needs to be loaded on demand with SP.SOD.registerSod and not by adding it with JSLink to the page.

So code in my question description would be wrapped in:

SP.SOD.registerSod('sp.workflowservices.js', _spPageContextInfo.layoutsUrl + '/sp.workflowservices.js');
    SP.SOD.registerSodDep('sp.workflowservices.js', 'sp.js');
    SP.SOD.executeFunc('sp.workflowservices.js', "SP.WorkflowServices.WorkflowServicesManager", function () { <code in question description> }

In order to have _spPageContextInfo available, you would need to wait for page load or, even faster, to poll for it with setInterval (cannot register another dependency because it is set in the page content, not an external script).

ライセンス: CC-BY-SA帰属
所属していません sharepoint.stackexchange
scroll top