All posts by JK

Change a specific K2 smartforms View background colour

Recently, I was asked this question on how to change the background colour of a specific View in a K2 smartforms Form. Like the following:

Change specific View background colour
Change specific View background colour

How to change a specific K2 smartforms View backgound colour

I’ve done some research and testing, and here is the CSS that will do the trick:

The number 2 in the line “nth-of-type(2)”, means the 2nd View in the Form. So if you need to just highlight the 3rd View, change the value to 3 and you are done.

Where to put this piece of style?

If you have a custom Theme and you want all Forms using this Theme to have the same effect, then you should add this style to your Theme’s CSS file.

If you only have to  make the change on a specific form, you can use a hidden Data Label to apply the theme. This is how to do it:

  1. Add a Data Label to your Form.

    Step 1 - Add Data Label
    Step 1 – Add Data Label
  2. Add the following line to the Text property. Remember to update the row number.

  3. Uncheck the Visible property. We don’t need the user to see this value.

    Step 3 - Uncheck Visibile
    Step 3 – Uncheck Visibile
  4. Check the Literal property. We need the control to parse the style tag.

    Step 4 - Check the Literal property
    Step 4 – Check the Literal property
  5. Finish the Form and you are done.


So that’s how you change a specific K2 smartforms View background colour.

Have Fun!

K2 Exchange OOFSettings

I’ve just posted K2 Exchange OOFSettings service broker at K2 Community site. This broker uses the EWS Managed API to access the Out-of-Office information on the Exchange server.

Where to get the broker?

The broker can be downloaded from:

Limitations of the K2 Exchange OOFSettings broker

This is the list of limitations of this broker:

  • Since the EWS API requires the user’s login name and password to execute the web service, the broker needs to run under SSO authentication mode. The selected authentication mode must be an AD security provider.
  • The email address will be retrieved via the System.DirectoryService.AccountManagement API, so make sure the user has a valid email address in AD.
  • When UseAutoDiscover service key is set to true, the broker will make use of the user’s email address to auto discover the Exchange server’s URL. See the following link on how to configure auto discover service for Exchange.

Service Instance Setup

As the broker requires the user’s login name and password to execute the EWS call, the service instance must be set up to use SSO Authentication Method and and AD security provider (by default, K2) must be selected.

SSO Authentication Mode
SSO Authentication Mode

The following are the description for the service keys:

Service Keys
Service Keys
  • UseAutoDiscover – Whether to lookup the URL using the Auto Discover service.
  • RequireHTTPS – Whether to enforce that the Exchange server’s URL needs to use the HTTPS scheme.
  • EwsURLFallback – The Exchange server’s EWS URL to be used when the broker fails to get a valid response from the Auto Discover service or when the UseAutoDiscover key is set to false.

Available Methods in K2 Exchange OOFSettings broker

This is the list of methods available:

Get OOF Settings

This method grabs the current selected user’s out of office settings from the Exchange server.

K2 Exchange OOFSettings - Get OOF Settings method
Get OOF Settings method

Turn On OOF Notification with Schedule

This method allows the user to turn on the out of office notification, set the reply email content and most importantly set the start and end date/time.

K2 Exchange OOFSettings - Turn On OOF Notification with Schedule
Turn On OOF Notification with Schedule

Turn On OOF Notification Permanently

Well, this method is the same as the previous one, except that there is no start and end date/time defined. It will be turned on as long as required.

K2 Exchange OOFSettings - Turn On OOF Notification Pernament
Turn On OOF Notification Permanent

Turn Off OOF Notification

This method will turn off the out of office notification.

K2 Exchange OOFSettings - Turn Off OOF Notification
Turn Off OOF Notification


Have Fun!

K2 smartforms Custom Control Icon

In this article, I’m going to describe how to add a K2 smartforms custom control icon. The official article is located at but it is not 100% accurate and contains mistakes in the CSS sample. Here’s the step by step guide:

Create the icon

The basic requirements of the K2 smartforms custom control icon is that it needs to be a 16×16 pixel image. In this sample, I’ll be using the Microsoft Paint application to create it.

  1. Search for your Paint application in your Windows Start menu and launch it.

    Find MS Paint
    Find MS Paint
  2. In your Paint application, click on Files > Properties.

    MS Paint Properties option
    MS Paint Properties option
  3. Set the Width and Height of the image to 16 and click OK.
  4. Draw your icon and save it. In my sample, I’ve saved my image in PNG format.

Adding the icon to your custom control

Now, here are the steps to add your K2 smartforms custom control icon:

  1. Add the icon to your VS project.

    Add icon to VS project
    Add icon to VS project
  2.  You will need to set the icon as a Embedded Resource. So right click on the icon, click on Properties and select Embedded Resource under Build Action.

    Set icon Build Action to Embedded Resource
    Set icon Build Action to Embedded Resource
  3. Add the icon as a WebResource in your control code file. Do take note that your resource name starts with the [Project Name], [Folder Name] and ends with the [Icon File Name], separated by a full stop (.). You should update the resource type, if you are not using a PNG file like me in this sample.

    Add icon as WebResource
    Add icon as WebResource
  4. You will need to add the K2 smartforms custom control icon styling in your control’s CSS file now. In the style sample below, you will need to replace a) the control name from “digital signature” to your control’s name and b) update the icon’s WebResource URL to the one you just created in the section above. Note: The CSS style provided at does not include spaces that separates the css class name. This causes the style to not function in your browser.
  5. Since we indicated WebResource usage in our CSS file, we will need to ensure PerformSubstitution attribute is set to true on the CSS WebResource declaration in the control file.

    PerformSubstitution = true
    PerformSubstitution = true
  6. Ensure that the CSS file reference is added in the constructor of your control class.  Replace the WebResource URL for your CSS file in the sample below.

View my K2 smartforms custom control icon!

Now, to view your new K2 smartforms custom control icon, you will need to:

  1. Compile the VS project and deploy your custom control.
  2. Ensure that your IIS has been reset.
  3. Clear your browser cache, log into your K2 Designer site and see your new K2 smartforms custom control icon in action!

    Look at my K2 smartforms custom control icon!
    Look at my K2 smartforms custom control icon!


List Sequence Number Display

K2 smartforms List Sequence Number Display

Recently, I’ve published a K2 smartforms custom control, List Sequence Number Display at K2 Community (

What does the List Sequence Number custom control do?

It helps you print running numbers on the first column of your List View.

List Sequence Number Display in action
Running number after performing a sort on the column header.

But I can already do that with a SQL View or SQL Stored Procedure…

Well, yes you can, but can your solution:

  1. Add running numbers without altering the original data source?
  2. Can it be do the same for data sources other than SQL?
  3. Can it keep the numbering across different pages? (i.e. pagination)
  4. Can it keep the numbering after a executing sort? (i.e. click on the column headers)
  5. Can it update the numbering adding a new record row? (i.e. adding a new row in a editable list)

So, if you solution can’t do it, then go on and try the List Sequence Number Display custom control! =)

Some things I’ve learned while developing the List Sequence Number Display control

Just to share some of the things I’ve learned from developing this custom control

The parent grid’s html entity ID is always the first set of Guid of my control’s Guid combination

If you look at the generated custom control’s ID via a browser’s Developer Tool, you will see something similar to the following:

Viewing the List Sequence Number Display control from Developer Tool
My custom control’s html entity ID

In my sample here, the div tag’s ID is “b113bc00-d8f7-4ce5-ae81-be2a0ecfe68d_5a10bfd9-f955-41b2-87f7-17e88cd158db”. So if I want to find the Grid which my control resides in, I just need to get the first set of GUID (b113bc00-d8f7-4ce5-ae81-be2a0ecfe68d), separated by the underscore symbol (‘_’) and look for the GUID combination in the ID of a “div” tag with the class name “grid”.

Viewing the List Sequence Number Display control from developer tool 2
Parent grid with the GUID as part of the ID.

This is the piece of JQuery I use to get my grid handle.

If you notice, it also checks if the parentIDString found starts with “00000000-“. This is to handle case where by the grid’s View is not within a Form.


Using MutationObserver

The grid has its own JavaScript class with does not expose any event handlers. So the only solution I can come up with is to use MutationObserver to listen to DOM changes. The biggest down side to this approach is that in Microsoft’s Internet Explorer (IE), only version 11 has a proper implementation of this API. In other browsers like Google Chrome, Firefox and Safari, it’s been the default since who knows when, so there’s no problem in executing the control in these browsers.

So what are the changes I’m listening to?

Based on my first set of  observations for display-only view:

  1. On the grid’s div tag, the “pagesize” attribute will be changed whenever a column sort occurs.
  2. On the grid’s div tag, the “listrefreshed” attribute will be written and changes when a list refresh occurs.
  3. On the grid’s div tag, the “actiontype” attribute will change when a row editing event occurs.

With these information, my first observer looks like this:

On my second observation on editable view:

  1. The “pagesize” attribute will not be written in the grid’s tag. So I can use this to confirm whether the current grid is an editable view.
  2. Since there’s no paging in an editable list view, the usual attributes in my first observation cannot be used to trigger the observer. From subsequent testing, I also found that there’s no other usable attributes to observe for change. My solution then is to listen to the “Column Headers” change by inserting my own custom attribute. It seems that when changes occur on an editable list view, it will refresh the column headers as well.

This is my 2nd observer for editable list view.

That’s all I have!

Well, as the section header says, that’s all I have learned from developing the List Sequence Number Display control. If you are interested in the codes, you can download it from the project from the link at the top of this post. Enjoy!

Use SmartObject upload file to SQL

K2 SmartObject can read and store files into SQL table via its File property. Files to be stored into SQL table will be automatically converted to base64 encoded string and when retrieved from SQL, it will be automatically converted back to binary.

In this article, we will see how to setup and use SmartObject upload file to SQL and test the function in  K2 smartforms.

Use SmartObject upload file to SQL

  1. We start by setting up the SQL table. The column that will be storing the file content will be created as a nvarchar(max) type.Create table and file content column
  2. If the Service Instance to the SQL database (in this case “FileUploadTest”) has not been created yet, create it. If the Service Instance already exists, refresh the Service Instance. Make sure the new table and its properties are available.Create or refresh Service Instance
  3. Right-click on the [dbo].[FileUpload] Service Object and select Create SmartObject.Create Smart Object function
  4. Give the new SmartObject an appropriate Name and click on Publish SmartObjectCreate the file upload SmartObject
  5. You should find the SmartObject at the Category it is created above.
    The created FileUpload SmartObject
  6. Next, find the SmartObject in K2 Designer and Edit it. Edit the SmartObject in K2 Designer
  7. Select the property that is supposed to hold the file content (i.e. fileContent in this case) and click on the Edit button.

    Edit the SmartObject’s fileContent property
  8. Now, this is the most important step. Change the Type to File and click OKChange the fileContent property type to File
  9. Lastly, Click Finish to complete editing the SmartObject and you are done.Click Finish to save


  1. Now, to test the SmartObject, we will use the Generate View feature. Right-click on the SmartObject and select Generate Views.
    Generate the View from the FileUpload SmartObject
  2. Select the checkbox under Item and click OK. This will generate an Item View. Select to create an Item View
  3. Select the newly created Item View and click on RunRun the generated View
  4. In the form, fill in the file Name, select a file in file Content field and click Create. This will create the record in SQL. Try create a record
  5. Take note of the generated ID field value and check against the SQL table created earlier. You will find the newly created record with the file content. Verify that the record is created in SQL
  6. To verify that the file was indeed saved successfully into the table, refresh the View used earlier, fill in the ID field value and click on Read button to load the file. Click on the file to download it and make sure it can be open in the appropriate application. Use the View to download the file to verify that it's working as expected

And that’s all on how to use SmartObject to upload file to SQL.

Have fun!

K2 Server Event Run As API

In K2 blackpearl workflow, you can specify “Run As” credentials on your Server Events. During workflow execution, the event will be ran using the specified account instead of the K2 Service Account (Note: All Server Events are ran using the service account by default). This feature is available in the K2 Studio and K2 Designer in Visual Studio and it is particularly useful when you need to run critical tasks like create create new AD account, provision Exchange mailbox etc. You do not want the K2 Service Account to have all these critical rights and no Developer should create these critical workflows without the K2 Administrator’s knowledge.

Updating K2 Server Event Run As via K2 Workspace
Updating K2 Server Event Run As via K2 Workspace

Now, the problematic part comes when the Development environment is running on the Development AD whereas the UAT and Production running on the Production AD. It is not possible to embed the credentials in the Server Events now and the only other option is to set it in the K2 Workspace (See article). Setting the credentials in K2 Workspace requires the Administrator to update it on every deployment since it is version specific. Things could get worst when there are multiple events to update in a workflow. To make things simple, we can write a console application that makes use of the workflow management api to update the credentials.

Let’s Code K2 Server Event Run As API

You can find a copy of the working codes at GitHub repository.

The logical steps go like this:

1. Connect to the Workflow Management Server. You need to run using a K2 Administrator account.

2. Get the Process Set for your process. Process Set contains the generic configuration for a Process and is the parent container for all the versions of this process.

3. Find the default Process version. This is required for “Run As” credential setting is version specific.

4. Find the Activity that holds the Server Event which you want to update.

5. Find the required Event.

6a. To set a credential.

6b. To remove the credential and event to service account.


And that’s the end of how to code K2 Server Event Run As API.



K2 smartforms control custom property

In this article, I’m going to show you how to add a property, MaxFileSize, to a K2 smartforms custom control.

Note: The focus of this article is all about adding a property and using it in your control. For the basics on how to create a K2 smartforms control, please visit K2 smartforms Developers Reference .

Adding a K2 smartforms control custom property

1. Add a new property to your control’s xml definition

In your control’s definition xml file, add a new Prop element under Properties. It should look like the following:

ID attribute is the new property’s name and InitialValue sets the default value when the control is first added to a View.

For more information about what each of the property’s attribute does, look at Control Definition XML File.

2. Add a Getter/Setter method in your control class to access the property value

You need this method to create and save the option values into the control so that you can retrieve it in your JavaScript later.

The method name should match the ID value set in the property earlier on. In the GetOption and SetOption method, use small caps for your option name (e.g. maxfilesize) as this will be the data-options attribute registered in the control’s html.

3. Reading the option values via JavaScript

Now, as I mentioned earlier, the options will be surfaced as data-options attributes in the control’s html. Use your browser’s in-built developer tools to look at the control’s html. It should look similar to this:

Notice that the maxfilesize value has been registered in the data-options attribute? This is the value set in the K2 Designer and you have access to it now. =)

So, last step. To get the value, just use the jQuery .data function to retrieve the data-options values. For me, I create a initialise function to handle the values initialization.


Good luck!

Form is Initializing or Initialized??

Since K2 smartforms 1.0.6, there is a new event, When the Form is Initialized, which runs after When the Form is Initializing completes. The new event allows the Designer to configure rules that runs after a form has been loaded (as ajax calls). This is an important feature as we can now load the form first (forms becomes interactive), then make X number of ajax calls to load the other controls/Views data (e.g. dropdown, List View, etc), instead of loading everything when the form loads. So what does this mean? Let me show you a simple example.

Firstly, let’s create a SmartObject that simulate a large result set or simply a very slow data source (imagining my Oracle and SAP in dev env…). I’ll be using a stored procedure that simulates a 5 seconds wait before returning my result set.

As the procedure name says, it is a very slow script and the corresponding spVSlowScript SmartObject is generated.

222 - SmO
The very slow data source

Next, I generate a View from spVSlowScript SmartObject and made sure to remove all Rules in the View. I don’t need the When the View is Initializing rule.

222 - View
The generated View.

With the View ready, I created a new Form and added 2 instances of the View into it.

222 - Form
The Form with 2 instance of the View.

Now, move on to the Form Rules configuration. You should see the When the Form is Initializing rule added for you.  Let’s edit this rule and change the views method to List. Change the execution block type to also for efficiency (You should use and block if one action returns much faster than the other).

222 - Form Rule
The Form Initializing rule

With the Rule above, the Form will finish loading when both the actions have been completed. Save the Form now.

Testing the Form Initializing rule

In this test, all loading actions (especially the slow view methods) are executed in the initialising rule.

Run the Form URL now and you will notice that the spinner overlay will cover the entire form and the form will only be usable/interactive after the 2 List methods completed the ajax call, which is after 5 seconds. The main interest point here is that your Form takes more than 5 seconds to load, which will fail most of your performance requirements. =(

222 - Initialising Spinner
Whole form spinner overlay.

Testing the Form Initialized rule

Now, let’s try changing the When the Form is Initialising rule to When the Form is Initialized and see the difference.

222 - Form Initialized Rule
Changed the rule to Form is Initialised.

When you run the form again, you will realise that the form actually loads almost immediately (<1 second) and each View will have a spinner overlay to indicate that it is performing an operation now (ajax call). While the spinner overlays are running, the User can start to interact with any controls that have completed loading (e.g. text boxes, etc). Now, you have passed your performance test. =)

222 - Initialized Spinner
Each View running its ajax call now.

Form is Initializing or Initialized?

So in short, you should place the actions that are required on form load in When the Form is Initializing rule and any other actions that could slow down a form loading or could be loaded at a later stage to the When the Form is Initialized rule.

The following is a list of actions that you can consider for the 2 events.

Some example of actions that could be added to the When the Form is Initializing rule

  • OpenWorklistItem action.
  • SmartObject or View methods that loads the main form content. (e.g. The Leave object in your Leave Application)
  • SmartObject or View methods that returns small number of records and the performance is good.
  • Hide/show controls and views. If you already know what to hide or show at this stage, you should do it here.

Some example of actions that could be added to the When the Form is Initialized rule

  • SmartObject or View methods that does not load the main form content and is slow in performance (e.g. large result set that takes a considerable time to load).
  • Hide/show controls and views. If the consideration logics are finalised after all actions in the initialising and initialised rule are completed. These will be added to the end of the initialised rule.

Have fun!

Using K2 WorklistCriteria

In my previous post, I’ve discussed on how to use K2 blackpearl’s SourceCode.Worklist.Client API for basic functions like start Process Instance, open Worklist, open Worklist Item and action a Worklist Item. All these functions are straight forward (that’s about all you can do with it) except the open Worklist  function.

Normally, when you use the OpenWorklist method, you will like to have some form of filtering. It could be a filter to show the user his/her tasks based on the current department website listed or some custom prioritization logic to help the user to focus on the tasks at hand. To make this filtering possible, you will need to make use of the WorklistCriteria class.

Using K2 WorklistCriteria

To use the WorklistCriteria class, you will need to carry out the same open/close workflow connection steps in my previous post, which I’m not going to repeat here. Once that’s done, you will need to create an instance of the class.

You will need to add your filters here, which we will discuss in the next section and lastly pass the object into the OpenWorklist method.

So in the full picture, your codes will look like this:

So if you execute the codes now, it will return all Worklist Items of the current user.

My result without filter

Filter Basics

Now, to add a filter, you will need to call on the AddFilterField which has 3 variations:

WCField is the list of properties you can filter on and they are pretty much self explanatory.

Do take note that WorklistItemStatus comparision uses the following values:

WCCompare lists the comparison operators you can use in the filter:

If you notice, there is no “greater than”, “greater than or equal”, “less than” and “less than or equal” operators here, so you will need to put some thoughts into your mathematical operations (=

WCLogical is the joining operator between 2 filters. This will be discussed in more details in a subsequent section.

SubField is a string value used to reference additional key names like Data Field name during comparison.

Object is a object value for your comparison.

So if you just want to filter and show all Worklist Item with “Available” status, the code will look like this:

When using my test Worklist, I’ll get:

Result showing all “Available” status only

Using AND and OR Logical Operators

Using the AND and OR filter is pretty straight forward.

In my AND join example, I’m going to create a filter that requires the Process Name to start with “C” and the Worklist Item status to be “Open”.

Result for Process start with “C” and status = “Open”

In my OR join example, I’m going to create a filter that requires the Worklist Item status to be “Available” or “Open”.

Status = “Available” OR “Open”

Using the Other Operators

Other than AND and OR operators, the following shows what the other operators does:

StartBracket: Draws the “(” operator for the given filter.

AndBracket: Adds the AND operator and closes the filter with a “)” operator.

OrBracket: Adds the OR operator and closes the filter with a “)” operator.

EndBracket: Closes the filter with a “)” operator, if you have a StartBracket earlier on

Filtering by Process or Activity Data/Xml Field

If you need to filter by Process or Activity Data or Xml Field, you will need to pass in the field name in the SubField like the following:


Well, the above details should get you through majority of your needs to create a custom Worklist. Enjoy!!

Providing a friendly error message for your K2 error

5 May 2017: I’ve updated this post for 4.6.10 and above here.

Be it on smartforms or your custom ASP.NET forms, the OpenWorklistItem call will return the following error if the current User did not pass the validation rule on K2 Server:

OpenWorklistItem error

For the K2 Designer and Admins, it’s a simple fact that the User is not the Destination User of this Activity. To the Users of this System, they will be like “What the heck are you trying to say?!?”. So how can we help the Users to better understand what is going on without calling us every time a cryptic message appears?

Find these cryptic out-of-box messages

These messages are stored as a template in [K2 blackpearl folder]\Host Server\bin\HostServerLogging.config.

The error message for ID 24411

In this file, you will find all the message templates used by K2. The first three numbers of the MsgID represents a logical section. So for example, MsgID starting with 244 are relating to security.

Of course, you can just modify this file directly, restart your K2 blackpearl Server services and all messages will be friendlier. But what happens on upgrade? Well, there’s a high chance that it will be replaced by the default copy in the installer, so it will be a hassle to make comparisons and update the entire list every time you upgrade. My take? Don’t touch this file unless you are willing to do all the additional work.

Friendly message via ASP.NET

Once you know the message you are looking out for, the rest will be using your try-catch block to capture the error thrown and look out for the MsgID in your error message body.

Friendly message via K2 smartforms

In smartforms, you will need to make use of the Error Handling condition – Error Occurred and read the message via the System Values > Error node.

  1. Open your Rule Configuration Wizard.

    Rule Wizard Configuration
  2. Add the Error Occurred condition. This will be executed when an error occurs in this Rule.

    Error Occurred condition
  3. Add the An advanced condition is true condition. This condition should be with Error Occurred to create a AND condition like the following:

    An advanced condition is true with Error occurred
  4. Click on an advance condition link, followed by the Add button to add a new row.

    Add a new row of condition
  5. From the Context Browser, expand System Values > Error. Drag the Error Message node and drop it to the Left column text box. Select Contains for the Operator and fill in the MsgID code you are looking for in the Right column text box. Click OK to save and close the dialog.

    Fill in the conditions
  6. Add your friendly message and any other rules(e.g. disable form, navigate to another form etc).

    Add a message
  7. Lastly, let’s test and see the result. 172-result


Have fun!