Creating a Custom User Task

In order to create a custom User Task, it is important to know how to create a Custom Wizard in K2. See the topic on creating a custom wizard for more detail. In addition, a Silverlight wizard and a Client Event Object needs to be created. Inject the following XML into ProcessExtenderEvent table with the ClientSide column set to True. The linking to the Categories and Context works the same as when creating a Custom Wizard.

<Event>

  <EventPageDetails>

    <FormPlugin>

      <File>SourceCode.WebDesigner.DesignerPlugin.DefaultClientEvent.bin</File>     1.

      <PopupPlugins>

        <PopupPlugin>SourceCode.WebDesigner.DesignerPlugin.DefaultClientEvent.Page1</PopupPlugin> 2.

      </PopupPlugins>

      <Validator/>

      <InitData/>

      <EventWizard>

        <Assembly>SourceCode.WebDesigner.Authoring.ClientEventForms, Version=4.0.0.0 , Culture=neutral, PublicKeyToken=16a2c5aaaa1b130d</Assembly> 3.

        <Class>SourceCode.WebDesigner.Authoring.ClientEvent.DefaultClientEvent</Class>    4.

      </EventWizard>

      <Images>

        <Default>DefaultClientEvent32_orange.png</Default>  5.

        <Originator>DefaultClientEvent32_green.png</Originator>

        <Manager>DefaultClientEvent32_red.png</Manager>

        <Runtime>DefaultClientEvent32.png</Runtime>

        <Wizard>DefaultClientEvent64_green.png</Wizard>

      </Images>

    </FormPlugin>

  </EventPageDetails>

</Event>

Node What it is

1. <File></File>

The Silverlight UI plugin similar to the Wizards

2. <PopupPlugin></PopupPlugin>

The Pages you want to display , there can be more than one PopupPlugin node for each page. The data for the plugin will then be saved to the ActivityXML in the FormPluginData node in the process XML

3. <Assembly></Assembly>

The assembly and class which will be called on deployment

4. <Class></Class>

The Class in the assembly which will add the client event. This class must have the following method which conforms to the one implemented from the base class (CreateDynamicClientEvent)

  • Need to reference SourceCode.WebDesigner.DynamicEvents.dll in the custom assembly
  • Need to implement ClientEventBase, IClientEvent and implement all the methods from the ClientEventBase
  • Sample Code, the “Generic Methods calls” region must be kept as is to add Notifications, Actions and Outcomes, _dynamicEvents.GetValue must always be used to resolve the values of the Watermark Expression builders (e.g.  TextBoxes) this will handle all the green block and text of the text box (See below)

5. <Default></Default>

The icons must be 32x32 except the Wizard icon which must be 64x64. The 32x32 icons can be the same, it's just easier to differentiate between Originator, Manager etc if they are different

usingSystem.Data;

usingSystem.Data.SqlClient;

usingSystem.IO;

usingSystem.Net;

usingSystem.Reflection;

usingSystem.Text;

usingSystem.Xml;

usingSystem.Xml.Linq;

usingSourceCode;

usingSourceCode.Configuration;

usingSourceCode.EnvironmentSettings.Client;

usingSourceCode.Framework;

usingSourceCode.Framework.Deployment;

usingSourceCode.ProjectSystem;

usingSourceCode.WebDesigner.Utils;

usingSourceCode.Workflow.Authoring;

usingSourceCode.Workflow.Common.Authentication;

usingSourceCode.Workflow.Common.WorkflowIntegration;

usingSourceCode.Workflow.Design;

usingSourceCode.Workflow.Design.SimpleRules;

usingSourceCode.Workflow.Expressions.Design;

usingSourceCode.Workflow.Functions.Design;

usingSystem;

usingSystem.Collections;

 

 

namespaceSourceCode.WebDesigner.Authoring.ClientEvent

{

   publicclassDefaultClientEvent:ClientEventBase,IClientEvent

    {

       publicvoidCreateDynamicClientEvent(XmlDocumentxmlProcess,XmlDocumentxmlInputData,XmlNodeactivity,ActivitynewActivity,ProcessnewProcess,stringUserName,refDynamicEvents_dynamicEvents,K2FieldSmartObjectServer,string_smartObjectServer,string_ContextType,string_CurrentEnvironment)

        {

           using(System.Security.Principal.WindowsImpersonationContextimpAppPool = System.Security.Principal.WindowsIdentity.Impersonate(IntPtr.Zero))

            {

                SourceCode.Workflow.Design.ClientEventnewEvent =newSourceCode.Workflow.Design.ClientEvent();

               ClientEventItemnewEventItem =null;

 

 

                newEvent.WizardDefinition =

                       newDefaultClientWizardDefinition();

                newEventItem = newEvent.EventItem;

 

                newEvent.Name = activity.Attributes["displayname"].Value +" Event";

                newEvent.Description = activity.Attributes["displayname"].Value +" Event";

 

                newEventItem.SendToInternet =true;

                newEventItem.InternetUrl = _dynamicEvents.GetValue(activity.SelectSingleNode("FormPluginData/TaskItem/URL").InnerXml, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType,false, _CurrentEnvironment);

               XmlNodeListparamaters = activity.SelectNodes("FormPluginData/TaskItem/Parameters/Parameter");

               if(paramaters.Count > 0)

                {

                    newEventItem.InternetUrl.Parts.Add(newValueTypePart("?"));

                   intcount = 0;

                   foreach(XmlNodeparaminparamaters)

                    {

                       K2FieldtempField = _dynamicEvents.GetValue(param.SelectSingleNode("ParameterValue").InnerText, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType,false, _CurrentEnvironment);

 

                       if(tempField.Parts[0].GetType().ToString().Equals("SourceCode.Workflow.Design.SerialNoFieldPart"))

                        {

                            newEventItem.InternetUrl.Parts.Add(newValueTypePart(param.SelectSingleNode("ParameterName").InnerText));

 

                           ArrayListinput1 =newArrayList();

                           ArrayListinput2 =newArrayList();

                           ArrayListinput3 =newArrayList();

 

                           //Text Input

                            input1.Add("System.String");

                            input1.Add("Text");

                            input1.Add("The source string.");

                            input1.Add("false");

                            input1.Add(tempField);

 

                           //Find Input

                            input2.Add("System.String");

                            input2.Add("Find");

                            input2.Add("The substring to find.");

                            input2.Add("false");

                            input2.Add(newK2Field(newValueTypePart("SN=")));

 

                            //Find Input

                            input3.Add("System.String");

                            input3.Add("Replace");

                            input3.Add("The substring to replace the found substrings.");

                            input3.Add("false");

                            input3.Add(newK2Field(newValueTypePart("=")));

 

                           K2FieldilFunctField =newK2Field(_dynamicEvents.GetInlineFunctionFieldPart("Replace","System.String","SourceCode.Workflow.Functions.TextManipulation, SourceCode.Workflow.Functions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=16a2c5aaaa1b130d", input1, input2, input3));

                            newEventItem.InternetUrl.Parts.Add(ilFunctField);

                        }

                       else

                        {

                            newEventItem.InternetUrl.Parts.Add(newValueTypePart(string.Concat(param.SelectSingleNode("ParameterName").InnerText,"=")));

                            newEventItem.InternetUrl.Parts.Add(_dynamicEvents.GetValue(param.SelectSingleNode("ParameterValue").InnerText, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType,false, _CurrentEnvironment));

                        }

                        count += 1;

 

                       if(count < paramaters.Count)

                        {

                            newEventItem.InternetUrl.Parts.Add(newValueTypePart("&"));

                        }

                    }

                }

                newEventItem.InternetPlatform ="ASP";

 

 

                #regionGeneric Methods calls

               //This mthod is in the base class

                CreateNotification((EventItem)newEventItem, newActivity, activity, xmlProcess, newProcess, SmartObjectServer, _dynamicEvents, _ContextType, _CurrentEnvironment);

 

               //This mthod is in the base class

                CreateEventActions(activity, newEvent, newProcess);

 

               //This mthod is in the base class

                CreateOutcomes(newActivity, activity, xmlProcess, newProcess, SmartObjectServer, _dynamicEvents, _ContextType, _CurrentEnvironment);

                newEvent.WizardDefinition.Status =WizardStatus.Executed;

                newActivity.Events.Add(newEvent);

                SourceCode.Workflow.Design.Outcome.Common.SyncActivityAndEventSucceedingRule(newEvent);

                #endregion

            }

        }

    }

}

It is important to note that the method needs to be defined as below to allow the backend to call the correct method upon deployment::

publicvoidCreateDynamicClientEvent(XmlDocumentxmlProcess,XmlDocumentxmlInputData,XmlNodeactivity,ActivitynewActivity,ProcessnewProcess,stringUserName,refDynamicEvents_dynamicEvents,K2FieldSmartObjectServer,string_smartObjectServer,string_ContextType,string_CurrentEnvironment)

The following needs to be called to resolve the textbox values from the user interface:

_dynamicEvents.GetValue 

K2 smartforms Product Documentation: User Guide4.6.11
Video Links Learn Support
No videos found for this article
K2 on YouTube
No Additional links found for this article
No self-learning content for this article
Try some scenarios...
No relevant support links available for this article