Jaap Vossers' SharePoint Blog

Just another WordPress.com site

ASPX Workflow Task Edit Forms – The Easy Way

with 5 comments

When developing custom Visual Studio workflows for SharePoint you have the choice to use InfoPath form templates or ASPX forms for your task edit forms. Many people go down the InfoPath route because implementing ASPX forms is not as simple as you would hope. Doing it the ASPX way involves creating a dedicated Content Type for each type of task that your Workflow creates. You could actually end up managing dozens of Task Content Types, which is no good.

So why does the InfoPath approach not require all these additional Content Types? When using InfoPath forms, in your Feature that deployed the Workflow Template, you associated every single InfoPath form template (.xsn) with an integer value – the Task Type. In your workflow code, upon creation of a workflow task using the CreateTask activity, you can specify which InfoPath template should be used as the task edit form for this particular task. You do this by setting the integer property TaskType on the TaskProperties property on the CreateTask activity. This value should correspond with the value that you used to map to your desired InfoPath form template in your Feature.

Under the hood, this integer value will be used to set the value for the Task Type field (which is defined on the hidden Content Type “Workflow Task”) on the List Item representing the task.

If you are doing it the InfoPath way, your InfoPath Form will be dynamically loaded by /_layouts/WrkTaskIP.aspx as you navigate to your task, based on the Task Type field value on the task List Item.

Hold on a second… why not build our own equivalent of WrkTaskIP.aspx that does the same trick, but instead of loading an InfoPath template it will load a custom Control!

I am assuming you know how to create custom application pages that reside in the _layouts folder. Create a page at /_layouts/yourproject/TaskEditor.aspx with your code behind somewhere in one of your assemblies.

We need to update the Workflow Task content type to have its EditFormUrl and DisplayFormUrl properties point to our new page. This needs to be done through code just once, for example with a Console Application or an ASPX page with code behind.

using(SPSite site = new SPSite("http://yoursite"))
{
  SPContentType ct = site.RootWeb.ContentTypes[new SPContentTypeId("0x010801")];

  ct.EditFormUrl = "_layouts/yourproject/TaskEditor.aspx";
  ct.DisplayFormUrl = "_layouts/yourproject/TaskEditor.aspx";
  ct.Update();
}

Alternatively, if you don’t like changing the out of the box Content Types, you could create one single Content Type that inherits from Workflow Task and set the EditFormUrl and DisplayFormUrl properties on this Content Type.

Right. Now that we have our TaskEditor.aspx page and our Content Type set up we can start implementing TaskEditor.aspx and its code-behind.

Firstly, add an asp:PlaceHolder to the markup of TaskEditor.aspx and add a field member into the code-behind class with a name equal to the ID so we can reference it from our code.

We then need to override the CreateChildControls method of our page. We will dynamically instantiate our control (we don’t know what to load yet, but we will soon find out!) in here and add it to the asp:PlaceHolder’s Controls collection.

Let’s read the value of the Task Type field on the task List Item.

int taskType = (int)SPContext.Current.ListItem["Task Type"];

You should create a method that returns an object of type Control and accepts the integer taskType parameter. The implementation of this method is really up to you. I implemented it in such a way that it uses Page.LoadControl() to load an ascx UserControl that is expected to reside at /_controltemplates/myproject/taskeditors/[taskType].ascx

Convention over configuration, I love it.

Next, after calling your method that creates the Control, you need to add it to the asp:PlaceHolder’s controls collection.

We are almost there! All we need to do is create a Button (either on the Page, or in your Control) to attach the “Complete Task” code to, so the Workflow can resume its execution – assuming an OnTaskChanged activity is waiting for the task to be updated.

All that is required for the implementation of the event handler is this:

SPContext.Current.ListItem.Update();

You could choose to set Status to Completed before updating it, or your could do this in your workflow by using a CompleteTask activity.

Obviously you would implement your custom controls based on your requirements, which may include things like validation + friendly validation messages, display of external data, capturing of additional data, and any other business logic. All things that are not too easy to achieve with InfoPath’s limited flexibility. And another cool thing is that the deployment process is so much easier now!

I hope this article was useful to you. I am sorry for not providing ready-to-run code, but it is merely the concept that I am trying to push to the outside world.

Thanks!

Written by jvossers

March 25, 2009 at 1:49 am

Posted in SharePoint, Workflow

5 Responses

Subscribe to comments with RSS.

  1. Thanks for sharing this article Japp, though it’s not such an easy way without any practical code…

    Keep going.
    Vinh

    Vinh

    May 11, 2009 at 8:48 am

  2. […] RunAsDate.This is a free task scheduler software for windows and is an easy way to schedule andASPX Workflow Task Edit Forms – The Easy Way Jaap Vossers …We will dynamically instantiate our control (we don’t know what to load yet, but we will soon find […]

    control task

    April 4, 2010 at 4:37 pm

  3. To create an application to be used as the custom aspx workfkow task edit form, create an empty sharepoint project in Visual Studio 2010. Next add an Application page template item to the project.

    You then proceed to implement ur code behind in the code behind file created for u. The using statements referencing the Sharepoint and System.Web namespaces are generated by the designer!

    Paul C. Metieh II

    November 13, 2010 at 1:23 pm

  4. Ideally code would be nice, I’m trying to implement this now and its painful 😐

    Komedee (@Komedee)

    October 19, 2012 at 4:00 am

  5. Hey Jaap,
    Thanks for sharing, that is a very nice way of doing it.
    Next beers are on me.

    Cheers
    Simon

    Simon Doy

    May 16, 2013 at 10:32 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: