Creating Item view user experience using List view in K2

Recently I encountered one of the request from a customer wherein they wanted to create some kind of feedback form with approximately 50 questions, and they don’t want the user to edit each and every row for providing their feedback which is basically the default behavior of K2 List View.

One dirty solution was to create an item view and hardcode all the questions but in case of any future changes, we have to revisit and do the modification every time.

Then we implemented something whose end result will look something like the below image.

DBTablesThe view which you can see in the screenshot is basically a list view but looking like an item view.

With this, we were able to achieve the dynamic loading of data and letting the user to provide their input without editing every single row.

So I wanted to share the approach which we have taken to achieve this requirement.

On a higher level, we followed the below steps:

  • Created a stored procedure to get the data from the backend and to return HTML code as per the design. (Unique ID per row)
  • Created the SmartObject of the stored procedure created in step 1 and create a list view on top of the generated SmartObject.
  • Capture the selection made by the user into a data label using JavaScript in XML or JSON format.
  • Pass the generated XML or JSON to the backend (SQL) to save the data.
  • Parse the XML or JSON in your stored procedure and save the data.

To explain the above steps I am going to create a sample table with some sample data and will walk you through to the different steps involved in this.

STEP 1: Create the following tables and add some test data in those tables

  • SectionHeader – This will store the different feedback header
  • Section – This will store the actual questions to be asked to the users.

DBTables

  • GetSectionsQuestions – Create a stored procedure that will be used to render the HTML radio button and text box control as per our required format.
-- Author: Divya Raj
-- Create date: 02 May 2020
-- Description: This will be used to load the list view as an item view
-- =============================================
CREATE PROCEDURE [dbo].[GetSectionsQuestions]
AS
BEGIN
SET NOCOUNT ON;

DECLARE @TEMP TABLE ( ID INT IDENTITY(1,1)
,UniqueRowID NVARCHAR(255)
,SectionHeaderID INT
,SectionID INT
,Description NVARCHAR(500)
,RadioButton VARCHAR(MAX)
,Comments VARCHAR(MAX)
,DisplayOrder INT
)

INSERT INTO @TEMP
SELECT CAST(SH.SectionHeaderID AS NVARCHAR(255)) + '-0',
SH.SectionHeaderID,
0,
'<B>'+CAST(SH.SectionHeaderID AS NVARCHAR(255))+'. '+SH.HeaderDesc+'</B>',
NULL,
NULL,
0
FROM SectionHeader SH

UNION

SELECT CAST(S.SectionHeaderID AS NVARCHAR(255)) + '-' + CAST(S.SectionID AS NVARCHAR(255)),
S.SectionHeaderID,
S.SectionID,
'&emsp;&emsp;'+CAST(S.SectionHeaderID AS NVARCHAR(255))+'.'+CAST(S.SectionID AS NVARCHAR(255))+' '+S.SectionDesc,
'<div style="text-align: center" class="textareaForXml" id="id'+CAST(S.SectionHeaderID AS NVARCHAR(255)) + '-' + CAST(S.SectionID AS NVARCHAR(255))+'"><span><label for id ="rbTrue"><input type="radio" name="'+CAST(S.SectionHeaderID AS NVARCHAR(255)) + '-' + CAST(S.SectionID AS NVARCHAR(255))+'" value="True" SectionHeaderId="'+CAST(S.SectionHeaderID AS NVARCHAR(255))+'" SectionId="'+CAST(S.SectionID AS NVARCHAR(255))+'" </input>True</label></span> &nbsp&nbsp<span><label for id ="rbTrue"><input type="radio" name="'+CAST(S.SectionHeaderID AS NVARCHAR(255)) + '-' + CAST(S.SectionID AS NVARCHAR(255))+'" value="False" SectionHeaderId="'+CAST(S.SectionHeaderID AS NVARCHAR(255))+'" SectionId="'+CAST(S.SectionID AS NVARCHAR(255))+'" </input>False</label></span></div>',
'<textarea id="textarea" class="textareaForXml" rows="2" cols="50"> </textarea>',
1
FROM SectionHeader SH INNER JOIN Section S ON SH.SectionHeaderID = S.SectionHeaderID


SELECT * FROM @TEMP
END


STEP 2:
Create a smartobject of the stored procedure (GetSectionsQuestions) created in step 1 and create a list view using the generated smartobject.

Make sure you have marked literal for the selected columns like Description, RadioButton, and Comments.

DBTables

STEP 3: Generate XML containing all the input details provided by the user.

Till step 2 the display part is completed and now we have to work on how can we store the values provided by the user.

Place 2 datalabel control and a button with the following properties:

  • hdnXMLReturn: Make sure you have named the control exactly like this as we will be storing the generated XML in this data label only. Set this as Visible = False
  • hdnJS: Set the property as Visible = False & Literal  = True.
  • Button Save: On click of this button we will store the values to the database which in our case will be SQL Server.

Configure the TRANSFER DATA rule on click of the Save button and pass the below JavaScript code to hdnJS datalabel

<script>
var returnXML = "";
//code to generate all the user input as XML
$("span div.textareaForXml").each(function (i)
{
    if (typeof $(this).find("[type=radio]:checked").val() === "undefined")
    { }
    else
    {
        var str = $(this).find("[type=radio]:checked").attr("name").split('_');
        var SectionValue = $(this).find("[type=radio]:checked").attr("value");
        var SectionHeaderId = $(this).find("[type=radio]:checked").attr("sectionheaderid");
        var SectionId = $(this).find("[type=radio]:checked").attr("sectionid");
        var SectionComment = $(this).closest('tr').find('td.last textarea').val();
        returnXML = returnXML + "<Section><SectionHeaderId>" + SectionHeaderId + "</SectionHeaderId><SectionId>" + SectionId + "</SectionId><SectionValue>" + SectionValue + "</SectionValue><SectionComment>" + SectionComment + "</SectionComment></Section>";
    }
});
//code to pass the generated XML to datalabel which will get passed to dB later
$("[name='hdnXMlReturn']").SFCLabel('option', 'text', '<Sections>' + returnXML + '</Sections>');
</script>

So by now, we have the complete XML of the details provided by the user in hdnXMLReturn datalabel.

STEP 4: Prepare to extract the data from XML and store it in a custom SQL table.

To achieve this create the below SQL artifacts:

  • Output table: This table will be used to store the values entered by users.
  • InsertFeedback stored procedure: This will be used to extract the data from the XML and store it to the Output table

Create the following columns for the Output table

[OutputID] [int] IDENTITY(1,1) NOT NULL,
[SectionHeaderID] [int] NULL,
[SectionID] [int] NULL,
[Value] [bit] NULL,
[Comments] [nvarchar](500) NULL,

Create the InsertFeedback stored procedure using the below script

-- =============================================
-- Author: Divya Raj
-- Create date: 02 May 2020
-- Description: This will be used to store the values entered by the user on K2 SMartform
-- =============================================
CREATE PROCEDURE [dbo].[InsertFeedback]
@XMLData XML
AS
BEGIN
SET NOCOUNT ON; 

INSERT INTO [dbo].[Output]
([SectionHeaderID]
,[SectionID]
,[Value]
,[Comments])
SELECT
COALESCE([Table].[Column].value('SectionHeaderId[1]', 'int'),0) as 'SectionHeaderID',
[Table].[Column].value('SectionId[1]', 'int') as 'SectionId',
[Table].[Column].value('SectionValue[1]', 'bit') as 'Value',
[Table].[Column].value('SectionComment[1]', 'varchar(max)') as 'Comment'
FROM @xmlData.nodes('/ Sections / Section') as [Table]([Column])


END

 

STEP 5: Final Configuration

Create the smartobject of the stored procedure created in step 4.

Then, edit the view created in step 2 and configure the following rules on click of the SAVE button

  • Transfer Data – as explained in step 3
  • Execute the SmartObject Method – Execute the smartobject created in Step 4 named “InsertFeedback” and pass “hdnXMLReturn” as an input parameter to this smartobject.

DBTables

Note: I have created a sample table to store the values but you can update the “InsertFeedback” stored procedure to store the values wherever you want.

With this, we have completed all the steps and our view is ready to be used.

In this way, we can create a List View behaving exactly like an Item View.

Thanks,

Enjoy Exploring K2!

Leave a Reply

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

WordPress.com Logo

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s