Tuesday, July 28, 2009
SharePoint Web Services Wrapper
By Hristo Yankov
Recently I noticed that a common reason for developers to seek help on the MSDN forum is related to difficulties understanding and/or utilizing the SharePoint Web Services. You can't blame the developers. It's much more convenient to work with an Object Oriented API, rather than exchanging XML messages with a Web Service. For example, take a look at the Lists.asmx -> GetListItems. Of course it's no rocket science, but it will sure save time if you could avoid dealing with the XML directly.
I spent some time researching if there is some kind of a library out there which provides 'managed' access to those Web Services. I.e. - work with .NET objects, rather than construct and parse XML elements. The closest thing I have found is this and it's totally outdated and incomplete. At least it's some reassurance to me that I am not missing the big picture and indeed, there might be people who would appreciate such framework.
So, I decided to start a project which will try to implement such .NET Object Oriented API around the SharePoint Web Services. Of course, for those corner weird cases (as well for the advanced developers), the underlying XML will still be accessible. Here is a good description of all the SharePoint services. My goal is to cover them all, eventually. I will start with the most commonly used ones.
It is hosted on CodePlex - http://spwebserviceswrapper.codeplex.com/
The project is not published yet, as there is no single line of code written yet. I will be doing this in my spare time. Once I shape it to my liking, it will become open source and everyone is welcome to contribute.
Got comments? Suggestions/Objections? There is a similar library already implemented? Please do let me know.
Hristo
Read more on this article...
Recently I noticed that a common reason for developers to seek help on the MSDN forum is related to difficulties understanding and/or utilizing the SharePoint Web Services. You can't blame the developers. It's much more convenient to work with an Object Oriented API, rather than exchanging XML messages with a Web Service. For example, take a look at the Lists.asmx -> GetListItems. Of course it's no rocket science, but it will sure save time if you could avoid dealing with the XML directly.
I spent some time researching if there is some kind of a library out there which provides 'managed' access to those Web Services. I.e. - work with .NET objects, rather than construct and parse XML elements. The closest thing I have found is this and it's totally outdated and incomplete. At least it's some reassurance to me that I am not missing the big picture and indeed, there might be people who would appreciate such framework.
So, I decided to start a project which will try to implement such .NET Object Oriented API around the SharePoint Web Services. Of course, for those corner weird cases (as well for the advanced developers), the underlying XML will still be accessible. Here is a good description of all the SharePoint services. My goal is to cover them all, eventually. I will start with the most commonly used ones.
It is hosted on CodePlex - http://spwebserviceswrapper.codeplex.com/
The project is not published yet, as there is no single line of code written yet. I will be doing this in my spare time. Once I shape it to my liking, it will become open source and everyone is welcome to contribute.
Got comments? Suggestions/Objections? There is a similar library already implemented? Please do let me know.
Hristo
Read more on this article...
Thursday, July 23, 2009
SharePoint bug udating title of uploaded xml
By Hristo Yankov
Another interesting case...
Programmatically upload an xml file (extension should be .xml) to SharePoint document library. As soon as you upload it, try to change the Title field of the item.
So here is the code:
For any non-xml extension files it works, but for xml files the Title doesn't change - it remains the same as the original name of the uploaded file. If you try doing this with another field of the item, it would work.
I came up with the following workaround:
Anyone has clue what's going on? Original MSDN forum thread is here.
Read more on this article...
Another interesting case...
Programmatically upload an xml file (extension should be .xml) to SharePoint document library. As soon as you upload it, try to change the Title field of the item.
So here is the code:
// We upload the file to SharePoint
SPFile file = Web.Files.Add(itemUrl, buff, true);
Web.Update();
string newTitle = "Sample Title";
SPListItem destItem = file.Item;
destItem.File.CheckOut();
// Try to change the title
destItem["Title"] = newTitle;
destItem.UpdateOverwriteVersion();
destItem.File.CheckIn(string.Empty,
SPCheckinType.MinorCheckIn);
For any non-xml extension files it works, but for xml files the Title doesn't change - it remains the same as the original name of the uploaded file. If you try doing this with another field of the item, it would work.
I came up with the following workaround:
SPFile file = Web.Files.Add(itemUrl, buff, true);
Web.Update();
string newTitle = "Sample Title";
SPListItem destItem = file.Item;
destItem.File.CheckOut();
destItem["Title"] = newTitle;
destItem.UpdateOverwriteVersion();
// Work-around start
destItem["Title"] = newTitle;
destItem.Update();
// Workaround end
destItem.File.CheckIn(string.Empty, SPCheckinType.MinorCheckIn);
Anyone has clue what's going on? Original MSDN forum thread is here.
Read more on this article...
Wednesday, July 22, 2009
Extending SharePoint Web Part
By Hristo Yankov
Hello!
SharePoint provides a lot of different out-of-the-box Web Parts. But sometimes we wish a particular web part behaved in a little different way, or have some small extra functionality. Or we may want to implement a heavily modified Web Part, based on already existing one.
Today, I will show you how to extend the functionality of an already existing web part.
We will take for example the SharePoint RSS Viewer. It loads an RSS feed and visualizes it in a web part on a SharePoint site. One of its visible properties in the UI is the Feed URL. It's a static string and doesn't allow any kind of dynamic parameters. Example:
Or
Those placeholders in my example are fictional, but you should get the idea of a dynamic value passed as a parameter to the service.
Our goal is to override the default behavior of the Feed URL field. We want to get to a point where we actually control how the Feed URL is being interpreted. We may want to replace placeholders with actual values, or do any other kind of adjustment of the URL, based on current and dynamic conditions. So here is the plan: we create a new web part, inherit the RSS Viewer web part and extend the Feed URL property.
Let's start. Here is how the RSS View part settings look like in edit mode:

See the RSS Feed URL field? That's what we are interested in.
Ok, start Visual Studio 2008 with the VSeWSS plugin installed. From the menu, start a new SharePoint -> Web Part project.

Give it a full trust

Change your namespace to something you prefer (for example, I will change it to HristoYankov). Rename the folder 'WebPart1' to 'RSSAggregatorWebPartDynamicParam'. It will rename all classes and files for you. In the Solution Explorer, expand Properties and open AssemblyInfo.cs. Add this to the bottom:
[assembly: AllowPartiallyTrustedCallers]
and this to the top:
using System.Security;
Your Solution Explorer should look similar to:

Right click on your project, click on Properties, go to the Debug tab and set the SharePoint site URL you will be deploying to.

Open the RSSAggregatorWebPartDynamicParam.webpart file and set Title and Description to whatever you like.
Now, after your project is setup, starts the interesting part. Let's inherit the RSS View control! What you need to do is...
Add this file as a reference - C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\microsoft.sharepoint.portal.dll. This is where the RSS View class is defined.
Open your RSSAggregatorWebPartDynamicParam.cs file and change your class from this:
public class RSSAggregatorWebPartDynamicParam : System.Web.UI.WebControls.WebParts.WebPart
to that:
public class RSSAggregatorWebPartDynamicParam : RSSAggregatorWebPart
And add this statement:
using Microsoft.SharePoint.Portal.WebControls;
Basically, we no longer inherit the basic WebPart class. Instead, we now inherit the whole functionality of the RSS Viewer web part and all of its user interface!
You can also delete this function, as we are not going to do any changes there.
protected override void CreateChildControls()
So far so good. Now let's override the Feed URL property! Add this to your class:
And add this statement:
using System.ComponentModel;
Three things to note here:
1. The FeedUrl property is the one which handles the URL which points to the RSS feed.
2. Note the attribute on top of the property. If you don't add it, it won't be visible in the UI
3. Note the 'new' keyword. This way we hide the underlying base FeedUrl property.
Ok, now we have control over the Feed URL. What we should do, is change the way FeedUrl is being returned. Change your get to look like:
And create this function:
So, in OverrideURL we can change any way we like the URL that is set in the User Interface and then return it modified. At this point, it is up to you how to utilize this capability.
For the purpose of the example, let's just look for the string #current_date# in the URL and replace it with the current date.
At the end, your code should look like:
Now, right click your project and do 'Deploy'. It should add a RSSAggregatorWebPartDynamicParam assembly to your GAC. When you go to your SharePoint site and do 'Edit Page' -> 'Add Web Part'

you should be able to see your newly created web part listed in the pop up. Add it to the page. Put it in Edit Settings mode and set the Feed Url to something like:
http://servername/service/Param1=#current_date#
It will be replaced by:
http://servername/service/Param1=06/06/2009 (for example)
NOTE: I just noticed this - as soon as you set the URL which contains the 'placeholder', the web part which is still in edit mode starts showing it with a replaced value (the date). I believe that the underlying value is still http://servername/service/Param1=#current_date#. So perhaps, in the method OverrideURL we should be taking into consideration if the web part is in edit mode. And if it is - just return the original parameter that was passed. Something like:
I will be checking this later. As usual, you can get the full source code here.
But basically that's it. With minimum amount of code and effort, we have extended the functionality of an already existing web part, to something that serves our concrete needs.
Hope this was helpful!
Read more on this article...
Hello!
SharePoint provides a lot of different out-of-the-box Web Parts. But sometimes we wish a particular web part behaved in a little different way, or have some small extra functionality. Or we may want to implement a heavily modified Web Part, based on already existing one.
Today, I will show you how to extend the functionality of an already existing web part.
We will take for example the SharePoint RSS Viewer. It loads an RSS feed and visualizes it in a web part on a SharePoint site. One of its visible properties in the UI is the Feed URL. It's a static string and doesn't allow any kind of dynamic parameters. Example:
- You can write: http://servername/service?Zip=92692
- But you can't: http://servername/service?Zip=#zip_of_current_location#
Or
- You can write: http://servername/service?IP=192.168.1.5
- But you can't: http://servername/service?IP=#current_ip#
Those placeholders in my example are fictional, but you should get the idea of a dynamic value passed as a parameter to the service.
Our goal is to override the default behavior of the Feed URL field. We want to get to a point where we actually control how the Feed URL is being interpreted. We may want to replace placeholders with actual values, or do any other kind of adjustment of the URL, based on current and dynamic conditions. So here is the plan: we create a new web part, inherit the RSS Viewer web part and extend the Feed URL property.
Let's start. Here is how the RSS View part settings look like in edit mode:

See the RSS Feed URL field? That's what we are interested in.
Ok, start Visual Studio 2008 with the VSeWSS plugin installed. From the menu, start a new SharePoint -> Web Part project.

Give it a full trust

Change your namespace to something you prefer (for example, I will change it to HristoYankov). Rename the folder 'WebPart1' to 'RSSAggregatorWebPartDynamicParam'. It will rename all classes and files for you. In the Solution Explorer, expand Properties and open AssemblyInfo.cs. Add this to the bottom:
[assembly: AllowPartiallyTrustedCallers]
and this to the top:
using System.Security;
Your Solution Explorer should look similar to:

Right click on your project, click on Properties, go to the Debug tab and set the SharePoint site URL you will be deploying to.

Open the RSSAggregatorWebPartDynamicParam.webpart file and set Title and Description to whatever you like.
Now, after your project is setup, starts the interesting part. Let's inherit the RSS View control! What you need to do is...
Add this file as a reference - C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\microsoft.sharepoint.portal.dll. This is where the RSS View class is defined.
Open your RSSAggregatorWebPartDynamicParam.cs file and change your class from this:
public class RSSAggregatorWebPartDynamicParam : System.Web.UI.WebControls.WebParts.WebPart
to that:
public class RSSAggregatorWebPartDynamicParam : RSSAggregatorWebPart
And add this statement:
using Microsoft.SharePoint.Portal.WebControls;
Basically, we no longer inherit the basic WebPart class. Instead, we now inherit the whole functionality of the RSS Viewer web part and all of its user interface!
You can also delete this function, as we are not going to do any changes there.
protected override void CreateChildControls()
So far so good. Now let's override the Feed URL property! Add this to your class:
[DefaultValue(""),
Resources("RSSWebpart_Property_FeedUrl_Text",
"RSSWebpart_ToolPart_Group",
"RSSWebpart_Property_FeedUrl_Description"),
Personalizable(PersonalizationScope.Shared),
WebBrowsable(true)]
public new string FeedUrl
{
get
{
return base.FeedUrl;
}
set
{
base.FeedUrl = value;
}
}
And add this statement:
using System.ComponentModel;
Three things to note here:
1. The FeedUrl property is the one which handles the URL which points to the RSS feed.
2. Note the attribute on top of the property. If you don't add it, it won't be visible in the UI
3. Note the 'new' keyword. This way we hide the underlying base FeedUrl property.
Ok, now we have control over the Feed URL. What we should do, is change the way FeedUrl is being returned. Change your get to look like:
get
{
return OverrideURL(base.FeedUrl);
}
And create this function:
private string OverrideURL(string url)
{
// TODO: Process the URL
return url;
}
So, in OverrideURL we can change any way we like the URL that is set in the User Interface and then return it modified. At this point, it is up to you how to utilize this capability.
For the purpose of the example, let's just look for the string #current_date# in the URL and replace it with the current date.
private string OverrideURL(string url)
{
return url.Replace("#current_date#", DateTime.Now.ToShortDateString();
}
At the end, your code should look like:
using System;
using System.Runtime.InteropServices;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Portal.WebControls;
using System.ComponentModel;
namespace HristoYankov
{
[Guid("03badfa9-53e4-401a-bc60-28db88b202ac")]
public class RSSAggregatorWebPartDynamicParam : RSSAggregatorWebPart
{
public RSSAggregatorWebPartDynamicParam()
{
}
[DefaultValue(""), Resources("RSSWebpart_Property_FeedUrl_Text", "RSSWebpart_ToolPart_Group", "RSSWebpart_Property_FeedUrl_Description"), Personalizable(PersonalizationScope.Shared), WebBrowsable(true)]
public new string FeedUrl
{
get
{
return OverrideURL(base.FeedUrl);
}
set
{
base.FeedUrl = value;
}
}
private string OverrideURL(string url)
{
return url.Replace("#current_date#", DateTime.Now.ToShortDateString());
}
}
}
Now, right click your project and do 'Deploy'. It should add a RSSAggregatorWebPartDynamicParam assembly to your GAC. When you go to your SharePoint site and do 'Edit Page' -> 'Add Web Part'

you should be able to see your newly created web part listed in the pop up. Add it to the page. Put it in Edit Settings mode and set the Feed Url to something like:
http://servername/service/Param1=#current_date#
It will be replaced by:
http://servername/service/Param1=06/06/2009 (for example)
NOTE: I just noticed this - as soon as you set the URL which contains the 'placeholder', the web part which is still in edit mode starts showing it with a replaced value (the date). I believe that the underlying value is still http://servername/service/Param1=#current_date#. So perhaps, in the method OverrideURL we should be taking into consideration if the web part is in edit mode. And if it is - just return the original parameter that was passed. Something like:
private string OverrideURL(string url)
{
if (this.NotInEditMode)
{
// Not in edit mode, perform changes
return url.Replace("#current_date#", DateTime.Now.ToShortDateString());
}
else
{
// We are in edit mode, return URL as is
return url;
}
}
I will be checking this later. As usual, you can get the full source code here.
But basically that's it. With minimum amount of code and effort, we have extended the functionality of an already existing web part, to something that serves our concrete needs.
Hope this was helpful!
Read more on this article...
Tuesday, July 21, 2009
SharePoint Solution Hello World Tutorial
By Hristo Yankov
Hi,
In this post, I will explain to you how to create your first SharePoint 2007 ASP.NET application. We will cover what tools you would need and what are the steps to creating a SharePoint Hello World app! I will keep the article short and clear on the necessary steps to be followed.
First, let's start with the tools. You will need Visual Studio 2008 SP1 (preferably) this freely available plugin for it Visual Studio 2008 extensions for Windows SharePoint Services 3.0. It is a toolset for developing custom SharePoint applications: Visual Studio project templates for Web Parts, site definitions, and list definitions; and a stand-alone utility program, the SharePoint Solution Generator.
We assume that you have setup and you do have available a SharePoint site, on which we will be deploying our solution.
So, start your Visual Studio 2008. From the menu choose to start a new Project.

Visual Studio will show this window. Select GAC and proceed.

Your Solution Explorer would look like this, initially:

We need to create a couple of folders. Recreate the folder structure described in the screenshot below:

Right click on HelloSharePointWorld and select add new item. Select text file, but name it "Hello.aspx"

Put the following content in your newly created ASPX page.
Note the PublicKeyToken value. It will be changed later. Now, create a new class in the App_Code folder. Name it Hello.aspx.cs. Your directory structure should look like:

The content of your Hello.aspx.cs should read:
Right click on your project, select Properties from the menu. Go to the Debug tab and set the hostname and port number of the SharePoint site where you want your project to be deployed.

Then save.
Now, right click on your project in Solution Explorer and rebuild it. Then right click on it and Deploy.

Now, open Windows Explorer and navigate to C:\WINDOWS\assembly. You should see an assembly called SharePointHelloWorld there. Right click it and select Properties.

Copy the Public Key Token (highlighted, note that it would be different for you) and click Cancel button. Now go back to your ASPX page in the project and replace the incorrect Public Key Token with the one you just copied.
Redeploy your application. Start Internet Explorer and navigate to http://[server name]:[port]/_layouts/HelloSharePointWorld/Hello.aspx
You should see something similar to:

Congratulations, you have created your first SharePoint solution. If you start the Central Admin for SharePoint and go to Operations -> Solution Management you should see a solution named sharepointhelloworld.wsp.
Let's add one more modification. Open the Hello.aspx.cs file and change it to:
By that, we utilize the code behind to output data on the screen. Rebuild, redeploy and refresh the page.

This is a good starting point for further learning by experimenting and example.
Of course, the full code for this project can be found here.
Read more on this article...
Hi,
In this post, I will explain to you how to create your first SharePoint 2007 ASP.NET application. We will cover what tools you would need and what are the steps to creating a SharePoint Hello World app! I will keep the article short and clear on the necessary steps to be followed.
First, let's start with the tools. You will need Visual Studio 2008 SP1 (preferably) this freely available plugin for it Visual Studio 2008 extensions for Windows SharePoint Services 3.0. It is a toolset for developing custom SharePoint applications: Visual Studio project templates for Web Parts, site definitions, and list definitions; and a stand-alone utility program, the SharePoint Solution Generator.
We assume that you have setup and you do have available a SharePoint site, on which we will be deploying our solution.
So, start your Visual Studio 2008. From the menu choose to start a new Project.

Visual Studio will show this window. Select GAC and proceed.

Your Solution Explorer would look like this, initially:

We need to create a couple of folders. Recreate the folder structure described in the screenshot below:

Right click on HelloSharePointWorld and select add new item. Select text file, but name it "Hello.aspx"

Put the following content in your newly created ASPX page.
<%@ Page Language="c#"
Inherits="Hello, SharePointHelloWorld, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=3cf44204a7ad1f1e"
MasterPageFile="~/_layouts/application.master"
%>
<asp:Content ID="Content1"
ContentPlaceHolderID="PlaceHolderMain"
runat="server">
<asp:Label ID="lblLabel1" runat="server" Text="Hello World!">
</asp:Label>
</asp:Content>
Note the PublicKeyToken value. It will be changed later. Now, create a new class in the App_Code folder. Name it Hello.aspx.cs. Your directory structure should look like:

The content of your Hello.aspx.cs should read:
using System;
using Microsoft.SharePoint.WebControls;
public partial class Hello : LayoutsPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
Right click on your project, select Properties from the menu. Go to the Debug tab and set the hostname and port number of the SharePoint site where you want your project to be deployed.

Then save.
Now, right click on your project in Solution Explorer and rebuild it. Then right click on it and Deploy.

Now, open Windows Explorer and navigate to C:\WINDOWS\assembly. You should see an assembly called SharePointHelloWorld there. Right click it and select Properties.

Copy the Public Key Token (highlighted, note that it would be different for you) and click Cancel button. Now go back to your ASPX page in the project and replace the incorrect Public Key Token with the one you just copied.
Redeploy your application. Start Internet Explorer and navigate to http://[server name]:[port]/_layouts/HelloSharePointWorld/Hello.aspx
You should see something similar to:

Congratulations, you have created your first SharePoint solution. If you start the Central Admin for SharePoint and go to Operations -> Solution Management you should see a solution named sharepointhelloworld.wsp.
Let's add one more modification. Open the Hello.aspx.cs file and change it to:
using System;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
public partial class Hello : LayoutsPageBase
{
protected Label lblLabel1;
protected void Page_Load(object sender, EventArgs e)
{
lblLabel1.Text = "Hello world! Time is: " +
DateTime.Now.ToString();
}
}
By that, we utilize the code behind to output data on the screen. Rebuild, redeploy and refresh the page.

This is a good starting point for further learning by experimenting and example.
Of course, the full code for this project can be found here.
Read more on this article...
Tags:
article,
example,
hello world,
how to,
hyankov,
learn,
sharepoint,
tutorial
iTechnology Forms Accelerator Tutorial
By Hristo Yankov
Hello!
Let's talk a little bit about K2 [blackpearl]/[blackpoint]. It is a great workflow solution, but there is a slight inconvenience - it lacks a User Interface! What does this mean? Well, it means that users can use K2 to create a workflow process, but when it comes to user interaction with this process, someone has to develop an ASP.NET page or Windows Forms application, to receive the user input and update the process. Even if you buy the expensive InfoPath, you may still need to do some coding. Wouldn't it be cool if even your business users could create a user interface for K2 workflow, without coding, all in one single environment?
Also, K2 is not too convenient for creating task-level workflows (many sequential tasks for the same user). Sure, you can queue multiple Client Events one after the other, but user has to click on his task items and load a new page for every one of them. It would be awesome if the user could stay on the same page and just complete his tasks, one after the other, with a single click.
In this blog post, I would like to show you how to use our very own tool - the iTechnology Forms Accelerator (iTFA)! It addresses both of the problems described above. I will demonstrate, step by step, how to create a user interface for a task-level workflow, from within the same environment where you create your K2 process - Visual Studio. Basically you create a form definition for the interface, while you create your K2 workflow. Then, when users open their worklist item(s), the definition is rendered as a web page. To see how it works, just follow the tutorial below.
We will create a simple task level workflow, for a fictional company which receives calls and delivers products. The process will go this way:

We start with a fresh new (and empty) process. Let's rename the process file to 'iTFATest1Process.kprx'.

First, let's integrate the K2 process with iTFA. In your toolbox, there should be an 'iTechnology Forms Accelerator Process' under the 'Process Wizards'.

Drag&drop it on the canvas. It will start a wizard. The first page is just a welcome.

Click Next and you will see:

The misc K2 field 'Form Engine URL' was created during the installation. It is supposed to store the URL to the forms rendering page. Basically, this is the page your users will be opening later (to work on their tasks), after you deploy your process. Here you have the chance to override the value, if you need to. You can just press 'Next'.

Here, you can setup the layout of the page the users will be presented with, when they open their task. It contains three different sections:

After doing it, note that the layout is empty. We need to drag and drop the web parts (located on the lower left) into the different sections of the layout. Let's put the History on top, Summary in the middle and Task (current) in the bottom one. Just drag&drop them in the appropriate sections.

Once we are satisfied with the layout our users will see, click Next.

This is where you can setup the Summary section. I would suggest to leave it empty for now. Later, when we know exactly what K2 fields we need, we will come back to this screen and set it up. Just click Next and then Finish to finalize this integration wizard.
After this is done, you should see the iTechnology Forms Accelerator Process integration icon, in the upper right corner of Visual Studio. We will click it later, to get back to this Process wizard and setup the Summary web part.

Note: The process we just finished, could have been started also by drag&dropping your first iTFA Client Event activity on the canvas. To avoid confusion, we did it the 'normal' way. Ok, now we can create our first user task (receive a call) in the workflow, which will be powered by iTFA user interface. There is an 'iTechnology Forms Accelerator Event' in the 'Event Wizards' section of Toolbox toobard.

Drag&drop it on the canvas. It will start another wizard. The first page you will see is the overview/welcome page.

Click Next. On this page, you give a name of your activity. Let's name it 'Receive a call'.

Click Next. Here, you can set summary and details of the task. They will be displayed to the user who is performing it, so you can use it to provide instructions.

Click Next. On this page of the wizard, you have to make a choice regarding the user interface of this particular task.

It can either:
No layout - no user input specific for this task, just Actions the user can take and Summary of the page.
New layout - we will specify new layout (fields) for the task
Copy layout - to copy the layout of another task. It is not available to us, as of right now, because we don't have other iTFA tasks in the workflow, this is the first one.
Let's go with 'New layout'. Here is the default new layout, which you should modify according to the needs of the current task (log a call).

As yo can see, the user input fields can be grouped in different 'sections'. Let's rename our default section to 'Client Information', by clicking the 'Edit' button of this section. We will also change the number of columns within the section to one (one field per row in this section).

And here is how it looks like after the change:

Ok, now let's think what K2 fields we need, to store the client information. Let's say:

We will add all of them as strings. Here is a screenshot after adding the K2 fields to the Process.

Now we can drag&drop any of those fields to our canvas on the left. Let's add all of them in the first (and only, for now) section. Drag&drop a field we created on the orange are of the section.

Let's add a new section to this task, of 2 columns. Click on the 'Add New Section' black button. Name it 'Other'.

We will add two more fields to it:
First, create the fields as we did before, then drag&drop them on this section.

Couple more things and we are done with this page. Let's make the fields in the first section required. Click on their 'Edit' buttons and mark them as required.

We also want to render the Company Address and Special Notes as multiline.

Let's render the 'Referred by' field as a dropdown with three different values to choose from:

And we are done, click Next. You are brought to the Actions screen. It initially has no actions. If you click Next, it will ask you to create the default 'Task Completed' action. Let's create two actions. One of them will be 'Take order' and another one 'User canceled'.

Click Next. You have to specify a 'destination' of the task. In other words - who will be performing it? Let's set it to the process originator, because it is the call center who will be starting a new instance of the process every time a client calls.

Then click Next. On the following page you can indicate that the user should receive an email notification when the task is available to him. In this case, it is not necessary so we don't check it.

Click Next and then finish. Now link the 'Start' process activity to the activity we just created. Create an empty server event activity and name it 'End'. Link the user canceled action to it. You should see something similar to:

Now, let's create our second iTFA activity in the workflow, which is the 'Take order'. Again, drag&drop the 'iTFA Event' on the canvas and follow the wizard. Let's create the following UI for this task:

Note that the K2 field behind Quantity is integer. Ok, let's adjust those values. We will make all of the fields required, Products and Shipping method will be dropdowns and we will display the 'Products' K2 field as 'Selected Product'.

Shipping method:

And we are done with the UI for this task. For actions - add 'User canceled' and 'Send to packing'. Destination should be the same - process originator. The workflow now looks like:

We need to create a task for the Packing department. Do the same drag&drop, this time, let's copy the layout from the 'Take order' activity.

We will see the same layout as the Take order activity. Delete the Shipping section, as it is not relevant in this case. In the Products section, make the fields 'read-only'.

(Quantity readonly)

Then create a new section called 'Packaging' and add a new field in it - Package ID, which will be required to be populated by the user executing this task. In our fictional company, it will indicate some inventory or storage number.
The end result should look like:

We need only one action for this task - Send to Shipping. Destination should be some guy in the Packaging department, but for our convenience, let's set the Originator again. Now your workflow looks like:

Create a task for shipping, where they see the Client Info, Shipping preference and Package ID. Let's copy from 'Client Information' again. Make all fields readonly. User interface should look lie:

Make Destination be the Originator again and Actions should be 'Shipped', linked to the end of the workflow.
And here is our workflow finalized:

Let's return back to the 'Summary' section and edit it. Click the iTFA integration icon and go to the last page of the wizard. Add any fields you would like all users to see, to the Summary canvas. Rename the section to 'Info'.

Now we just need to deploy it. Click the 'deploy' button which starts the wizard and just click Next and Finish.

If there were other users (other from Originator) in the process, make sure you give them rights to the process in the K2 Workspace.
You can now start a new instance of your process from the Workspace or you can open our page (same one as the value of Form Engine URL):
http://[servername]/ITFA/ITFARender.aspx?ProcName=iTFATest1\iTFATest1Process&Folio=TestFolio
You can use that capability to incorporate it into an existing site or another software. For instance, your call center employees could start a new call log by clicking a link in their portal.
So, let's review what the users will see. Here is the first screen, where the user logs the call:

As soon as the user populates the information and clicks on the Take order action (link on the bottom of the page), he sees the following screen:

Here the call center logs the product the user is interested it and quantity. We then send it to Packing. Here the Packing guys see what they need to pack and then assign an ID to the package, which will be used by the Shipping department.

They send it to Shipping. Here, the Shippers see the Package ID (so they can find it in the warehouse), see the address to ship to, special notes and shipping method.

And that's it! Shipper finishes the task, workflow is complete.
Benefits?
You can also check out our videos on YouTube.
Thanks,
Hristo Yankov
Read more on this article...
Hello!
Let's talk a little bit about K2 [blackpearl]/[blackpoint]. It is a great workflow solution, but there is a slight inconvenience - it lacks a User Interface! What does this mean? Well, it means that users can use K2 to create a workflow process, but when it comes to user interaction with this process, someone has to develop an ASP.NET page or Windows Forms application, to receive the user input and update the process. Even if you buy the expensive InfoPath, you may still need to do some coding. Wouldn't it be cool if even your business users could create a user interface for K2 workflow, without coding, all in one single environment?
Also, K2 is not too convenient for creating task-level workflows (many sequential tasks for the same user). Sure, you can queue multiple Client Events one after the other, but user has to click on his task items and load a new page for every one of them. It would be awesome if the user could stay on the same page and just complete his tasks, one after the other, with a single click.
In this blog post, I would like to show you how to use our very own tool - the iTechnology Forms Accelerator (iTFA)! It addresses both of the problems described above. I will demonstrate, step by step, how to create a user interface for a task-level workflow, from within the same environment where you create your K2 process - Visual Studio. Basically you create a form definition for the interface, while you create your K2 workflow. Then, when users open their worklist item(s), the definition is rendered as a web page. To see how it works, just follow the tutorial below.
We will create a simple task level workflow, for a fictional company which receives calls and delivers products. The process will go this way:
- Call center - Receives a new call and logs the client details
- Call center - Either logs what the client orders, or marks the order as 'canceled' (if user changed mind during the call)
- Packing Department - They receive the order
- Shipping department - They receive the order (package ID) and address to ship to

We start with a fresh new (and empty) process. Let's rename the process file to 'iTFATest1Process.kprx'.

First, let's integrate the K2 process with iTFA. In your toolbox, there should be an 'iTechnology Forms Accelerator Process' under the 'Process Wizards'.

Drag&drop it on the canvas. It will start a wizard. The first page is just a welcome.

Click Next and you will see:

The misc K2 field 'Form Engine URL' was created during the installation. It is supposed to store the URL to the forms rendering page. Basically, this is the page your users will be opening later (to work on their tasks), after you deploy your process. Here you have the chance to override the value, if you need to. You can just press 'Next'.

Here, you can setup the layout of the page the users will be presented with, when they open their task. It contains three different sections:
- History - in this section of the page, the user will see who and when finished what task in the current workflow
- Summary - Visible in all activities (tasks) of the workflow. You can use to show the same fields to all users of the workflow.
- Task - The area of the page which shows the current task details

After doing it, note that the layout is empty. We need to drag and drop the web parts (located on the lower left) into the different sections of the layout. Let's put the History on top, Summary in the middle and Task (current) in the bottom one. Just drag&drop them in the appropriate sections.

Once we are satisfied with the layout our users will see, click Next.

This is where you can setup the Summary section. I would suggest to leave it empty for now. Later, when we know exactly what K2 fields we need, we will come back to this screen and set it up. Just click Next and then Finish to finalize this integration wizard.
After this is done, you should see the iTechnology Forms Accelerator Process integration icon, in the upper right corner of Visual Studio. We will click it later, to get back to this Process wizard and setup the Summary web part.

Note: The process we just finished, could have been started also by drag&dropping your first iTFA Client Event activity on the canvas. To avoid confusion, we did it the 'normal' way. Ok, now we can create our first user task (receive a call) in the workflow, which will be powered by iTFA user interface. There is an 'iTechnology Forms Accelerator Event' in the 'Event Wizards' section of Toolbox toobard.

Drag&drop it on the canvas. It will start another wizard. The first page you will see is the overview/welcome page.

Click Next. On this page, you give a name of your activity. Let's name it 'Receive a call'.

Click Next. Here, you can set summary and details of the task. They will be displayed to the user who is performing it, so you can use it to provide instructions.

Click Next. On this page of the wizard, you have to make a choice regarding the user interface of this particular task.

It can either:
No layout - no user input specific for this task, just Actions the user can take and Summary of the page.
New layout - we will specify new layout (fields) for the task
Copy layout - to copy the layout of another task. It is not available to us, as of right now, because we don't have other iTFA tasks in the workflow, this is the first one.
Let's go with 'New layout'. Here is the default new layout, which you should modify according to the needs of the current task (log a call).

As yo can see, the user input fields can be grouped in different 'sections'. Let's rename our default section to 'Client Information', by clicking the 'Edit' button of this section. We will also change the number of columns within the section to one (one field per row in this section).

And here is how it looks like after the change:

Ok, now let's think what K2 fields we need, to store the client information. Let's say:
- Client Names - Names of the person who called us
- Company Name - Name of the company this person works for
- Company Address - Address of the company
- Phone Number - Phone number we can use to reach the person/company

We will add all of them as strings. Here is a screenshot after adding the K2 fields to the Process.

Now we can drag&drop any of those fields to our canvas on the left. Let's add all of them in the first (and only, for now) section. Drag&drop a field we created on the orange are of the section.

Let's add a new section to this task, of 2 columns. Click on the 'Add New Section' black button. Name it 'Other'.

We will add two more fields to it:
- Special Notes - where user can input any special notes about the client
- Referred By - specify how client found us
First, create the fields as we did before, then drag&drop them on this section.

Couple more things and we are done with this page. Let's make the fields in the first section required. Click on their 'Edit' buttons and mark them as required.

We also want to render the Company Address and Special Notes as multiline.

Let's render the 'Referred by' field as a dropdown with three different values to choose from:

And we are done, click Next. You are brought to the Actions screen. It initially has no actions. If you click Next, it will ask you to create the default 'Task Completed' action. Let's create two actions. One of them will be 'Take order' and another one 'User canceled'.

Click Next. You have to specify a 'destination' of the task. In other words - who will be performing it? Let's set it to the process originator, because it is the call center who will be starting a new instance of the process every time a client calls.

Then click Next. On the following page you can indicate that the user should receive an email notification when the task is available to him. In this case, it is not necessary so we don't check it.

Click Next and then finish. Now link the 'Start' process activity to the activity we just created. Create an empty server event activity and name it 'End'. Link the user canceled action to it. You should see something similar to:

Now, let's create our second iTFA activity in the workflow, which is the 'Take order'. Again, drag&drop the 'iTFA Event' on the canvas and follow the wizard. Let's create the following UI for this task:

Note that the K2 field behind Quantity is integer. Ok, let's adjust those values. We will make all of the fields required, Products and Shipping method will be dropdowns and we will display the 'Products' K2 field as 'Selected Product'.

Shipping method:

And we are done with the UI for this task. For actions - add 'User canceled' and 'Send to packing'. Destination should be the same - process originator. The workflow now looks like:

We need to create a task for the Packing department. Do the same drag&drop, this time, let's copy the layout from the 'Take order' activity.

We will see the same layout as the Take order activity. Delete the Shipping section, as it is not relevant in this case. In the Products section, make the fields 'read-only'.

(Quantity readonly)

Then create a new section called 'Packaging' and add a new field in it - Package ID, which will be required to be populated by the user executing this task. In our fictional company, it will indicate some inventory or storage number.
The end result should look like:

We need only one action for this task - Send to Shipping. Destination should be some guy in the Packaging department, but for our convenience, let's set the Originator again. Now your workflow looks like:

Create a task for shipping, where they see the Client Info, Shipping preference and Package ID. Let's copy from 'Client Information' again. Make all fields readonly. User interface should look lie:

Make Destination be the Originator again and Actions should be 'Shipped', linked to the end of the workflow.
And here is our workflow finalized:

Let's return back to the 'Summary' section and edit it. Click the iTFA integration icon and go to the last page of the wizard. Add any fields you would like all users to see, to the Summary canvas. Rename the section to 'Info'.

Now we just need to deploy it. Click the 'deploy' button which starts the wizard and just click Next and Finish.

If there were other users (other from Originator) in the process, make sure you give them rights to the process in the K2 Workspace.
You can now start a new instance of your process from the Workspace or you can open our page (same one as the value of Form Engine URL):
http://[servername]/ITFA/ITFARender.aspx?ProcName=iTFATest1\iTFATest1Process&Folio=TestFolio
You can use that capability to incorporate it into an existing site or another software. For instance, your call center employees could start a new call log by clicking a link in their portal.
So, let's review what the users will see. Here is the first screen, where the user logs the call:

As soon as the user populates the information and clicks on the Take order action (link on the bottom of the page), he sees the following screen:

Here the call center logs the product the user is interested it and quantity. We then send it to Packing. Here the Packing guys see what they need to pack and then assign an ID to the package, which will be used by the Shipping department.

They send it to Shipping. Here, the Shippers see the Package ID (so they can find it in the warehouse), see the address to ship to, special notes and shipping method.

And that's it! Shipper finishes the task, workflow is complete.
Benefits?
- We built user interface for three different departments of the company without even writing a single line of code.
- We did it without leaving the Visual Studio environment.
- We did it while we were building the workflow itself.
- This whole tutorial can be complete for less than 10 minutes. How many days/weeks would your IT department need to do it the 'regular' way?
- Many other...
You can also check out our videos on YouTube.
Thanks,
Hristo Yankov
Read more on this article...
Tags:
article,
custom,
forms accelerator,
how to,
hyankov,
itechnology,
itfa,
k2,
sharepoint,
tutorial,
user interface,
wizards
Subscribe to:
Posts (Atom)