In this article, I’m going to describe how to add a K2 smartforms custom control icon. The official article is located at help.k2.com 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.
Search for your Paint application in your Windows Start menu and launch it.
In your Paint application, click on Files > Properties.
Set the Width and Height of the image to 16 and click OK.
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:
Add the icon to your VS project.
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.
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.
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 help.k2.com does not include spaces that separates the css class name. This causes the style to not function in your browser.
.tree li.digitalsignature-control > a,
.tree li.digitalsignature-control > span,
.tree li.digitalsignature-control.children > a,
.tree li.digitalsignature-control.children.open > a,
.tree li.digitalsignature-control.children.closed > a,
What does the List Sequence Number custom control do?
It helps you print running numbers on the first column of your List View.
But I can already do that with a SQL View or SQL Stored Procedure…
Well, yes you can, but can your solution:
Add running numbers without altering the original data source?
Can it be do the same for data sources other than SQL?
Can it keep the numbering across different pages? (i.e. pagination)
Can it keep the numbering after a executing sort? (i.e. click on the column headers)
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:
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”.
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.
So what are the changes I’m listening to?
Based on my first set of observations for display-only view:
On the grid’s div tag, the “pagesize” attribute will be changed whenever a column sort occurs.
On the grid’s div tag, the “listrefreshed” attribute will be written and changes when a list refresh occurs.
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:
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.
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.
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!
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
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.
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.
Right-click on the [dbo].[FileUpload] Service Object and select Create SmartObject.
Give the new SmartObject an appropriate Name and click on Publish SmartObject.
You should find the SmartObject at the Category it is created above.
Next, find the SmartObject in K2 Designer and Edit it.
Select the property that is supposed to hold the file content (i.e. fileContent in this case) and click on the Edit button.
Now, this is the most important step. Change the Type to File and click OK.
Lastly, Click Finish to complete editing the SmartObject and you are done.
Now, to test the SmartObject, we will use the Generate View feature. Right-click on the SmartObject and select Generate Views.
Select the checkbox under Item and click OK. This will generate an Item View.
Select the newly created Item View and click on Run.
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.
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.
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.
And that’s all on how to use SmartObject to upload file to SQL.
K2 Smartform is a rapid development tool that provide a WYSIWYG interface. There’s a lot of plus point to this as this closely resemble the visual studio designer or even dreamweaver and K2 have place alot of thought in the Smartform product design and a whole lot of controls are available out of the box.
However, the downside here is that since the K2 Smartform only work within the K2’s technology ecosystem, to extend the capability of the Smartform such as cooking your own controls or even using those commercially available (e.g. Telerik) are limiting.
In this article, we will be writing a mulit part series to show you guys how to build your own custom control.
The K2 Smartform is design such that its almost similar to any custom user control on ASP.NET or Sharepoint Webpart in terms of architecture.
To get started building a K2 Smartform custom control, head over to the following url and install the template that the community have release to help everyone get started.
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.
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:
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.
INSERT INTO@tmpTbl VALUES('A1','B1','C1');
INSERT INTO@tmpTbl VALUES('A2','B2','C2');
INSERT INTO@tmpTbl VALUES('A3','B3','C3');
As the procedure name says, it is a very slow script and the corresponding spVSlowScript SmartObject is generated.
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.
With the View ready, I created a new Form and added 2 instances of the View into it.
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).
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. =(
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.
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. =)
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
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.
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:
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.
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.
// do something else
Console.Writeline("Sorry, you do not have the rights to work on this task.");
Console.Writeline("Sorry, an error had occurred. Please contact the System Administrator and provide the following message:<br/>"+ex.Message);
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.
Open your Rule Configuration Wizard.
Add the Error Occurred condition. This will be executed when an error occurs in this Rule.
Add the An advanced condition is true condition. This condition should be with Error Occurred to create a AND condition like the following:
Click on an advance condition link, followed by the Add button to add a new row.
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.
Add your friendly message and any other rules(e.g. disable form, navigate to another form etc).