Skip to main content

Cloud

Start a custom workflow from the context menu dropdown

I was tasked with giving the users the ability to start a custom workflow on a document via the context menu dropdown in a document library. I settled on a strategy that would add a link to the dropdown and be flexible enough to reuse for several workflows.

The basic steps are:

1. Add a link to the context menu dropdown

2. Create a custom ASPX page that will handle the redirection to the workflow initiation form

3. Deploy your solution

The first thing to do is to add the link to the dropdown. This link will call up the custom ASPX form that you will build in the next step. Notice the tokens in the URL. MOSS makes several tokens available, including the ~site, {ListId}, and {ItemId} used below. The Template ID is the GUID that you used to deploy your workflow.

Create an XML file that looks something like this:

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<CustomAction

Id="DocLibMenu.ItemToolbarStartWorkflow"

RegistrationType="List"

RegistrationId="10000"

Location="EditControlBlock"

Sequence="106"

Title="My Workflow">

<UrlAction Url="~site/_layouts/StartWorkflow.aspx?ListID={ListId}&amp;ID={ItemId}&amp;WFTemplateID=dc904e02-bebe-4581-aa4f-ae4e843d1111"/>

</CustomAction>

</Elements>

Now create your ASPX page, we’ll call it StartWorkflow.aspx. The ASPX file itself can be pretty simple, just the standard MOSS headers and a string variable that you’ll define in the code behind. (something like <%=output %>). Its really only used for messages to the user in case something goes wrong.

In the code behind, you’ll want to inherit from the MOSS LayoutsBasePage:

public class StartWorkflow : LayoutsPageBase

You’ll read the QueryString variables:

Guid listId = new Guid(Request.QueryString["ListID"]);

Guid wfTemplateId = new Guid(Request.QueryString["WFTemplateID"]);

int itemID = int.Parse(Request.QueryString["ID"]);

Now get the List and Item objects for the item that you’re running the workflow against:

SPList theList = Web.Lists[listId];

SPListItem theItem = theList.GetItemById(itemID);

Get the workflow association object:

SPWorkflowAssociation theWFAssociation = theList.WorkflowAssociations.GetAssociationByBaseID(wfTemplateId);

Check if the association is valid and enabled:

if (theWFAssociation == null || theWFAssociation.Enabled == false)

{

isError = true;

output = "The workflow will not start because workflows of this type are not currently enabled on the library";

}

Now find if there are any running instances of the requested workflow. You can only have one running instance of a workflow per list item. This is a MOSS limitation that I’ll address in a later blog entry – unfortunately not with a solution.

if (theItem.Workflows.Count > 0)

{

foreach (SPWorkflow currentWF in theItem.Workflows)

{

if (currentWF.ParentAssociation.BaseTemplate.Id == wfTemplateId && currentWF.InternalState == SPWorkflowState.Running)

{

isError = true;

output = "The workflow will not start because a previous workflow of this type is still active and has yet to be completed.";

}

}

}

If there are no errors, then go ahead and redirect to the workflow initiation form.

if (!isError)

{

SourceURL = theList.DefaultViewUrl;

string InstantiationUrl = theWFAssociation.InstantiationUrl;

TemplateID = theWFAssociation.Id;

theURL = Web.Url + "/" + InstantiationUrl + "?List=" + listId.ToString() + "&ID=" + Request.QueryString["ID"] + "&TemplateID=" + TemplateID.ToString() + "&Source=" + SourceURL;

Response.Redirect(theURL);

}

To deploy your solution, you’ll need to do a few things:

1. Deploy the dropdown link as a feature.

2. Strong-name and compile the ASPX page and deploy the DLL to the GAC.

3. Put your ASPX file the LAYOUTS directory (C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTS).

As I mentioned before, one nice thing about this solution is that the StartWorkflow.aspx form is pretty generic and can be reused for just about any workflow you create. Just change the WorkflowId GUID value in the QueryString when you call the page up to the GUID you used to define the workflow when you deployed it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.