How To Build A Simple Form Widget - Example 3

Last published at: June 27th, 2023

Building, Configuring and Executing a complex Form Widget example 3

This Document will explain how to write a new complex Form Widget, configure it using Manage Form Widget, use the widget within the forms designer and render the Widget within a form instance.  This Widget will perform operations at client side and server side with database connectivity.

Form Widgets

 Following is a list of standard Form Widgets (html controls) used in the forms designer.

  1. Button
  2. Input
  3. Select
  4. Checkbox
  5. Radio button
  6. Table
  7. Image
  8. Label
  9. Hr
  10. File
  11. iFrame

 

Custom Form Widgets

Custom Form Widget is the combination of single or multiple html controls providing UI functionality. A Form Widget is made up with the following components:

  1. HTML section
  2. Script section
  3. Server side dll
  4. Icon file
  5. Configure Form Widget

 

 

How to build the custom Form Widget

First create the empty html file with Widget name ex: Create a widget as ‘lookupviewdata’ where the name of html file should be ‘lookupviewdata.html’.This Form Widget calculates live lookupviewdata based on US Dollar.

Basic structure of Form Widget should be as following

<!--lookupviewdata UI Start-->

<formWidget id="formWidget_form" type="lookupviewdata">

             .

             .

             .

</formWidget>

<!-- lookupviewdata UI End-->

<!-- lookupviewdata JS Start -->

<script>

             .

             .

             .

 

</script>

<!—lookupviewdata JS Start -->

 

 

 

 
  • The code should be divided in to two sections Html Section and Script Section 

 

1. Html Section

Basic structure of HTML should be as following

<!-- lookupviewdata UI Start-->

<formWidget id="formWidget_form" type="lookupviewdata">

         <div>

             .

             .

             .

         </div>

</formWidget>

<!-- lookupviewdata UI End-->

 

 

  • Make sure to have UI Start and End comments, comment section should be enclosed with 

               <!--  --> tag.

  • After the first comment tag, the first custom tag must be <formWidget … > … </formWidget>
  • By default, <formWidget> should have two attributes, Id and type. User can add other attributes as per their requirements.In this example, there are additional data attributes which are explained in the following example .
  • <formWidget> id must be id="formWidget_form" which sould be the unique id, and is used across all custom Form Widgets within the application.
  • <formWidget> type must have the same name as html file name. For example – we are using lookupviewdata.html so the type="lookupviewdata".
  • <div> tag must be followed by <formWidget> tag, and all the style="…" attribute properties should be used within this <div> tag. However, the style="…" attribute should not be added within the <formWidget> tag.

 

HTML controls, id and other attributes within the main div tag

<!--lookupviewdata UI Start-->

<formWidget id="formWidget_form" type="lookupviewdata">

 <div>

<table>

            <tr>

                <td>

                    <table>

                        <tr>

                            <td><label id="formWidget_lblSearch" style="margin-bottom10px;">Search Data:</label></td>

                            <td><input id="formWidget_txtSearch" class="input-large" type="text" /></td>

                            <td><input id="formWidget_btnSearch" style="margin-bottom10px;" type="button" value="Search" onclick="lookupData(this, $('#formWidget_txtSearch'),'formWidget_tblData')" /></td>

                        </tr>

                    </table>

                </td>

            </tr>

            <tr>

                <td colspan="3">

                    <table class="table " style="width:100%" id="formWidget_tblData"></table>

                </td>

            </tr>

             </table>

</div>

</formWidget>

<!--lookupviewdata UI End-->

 

 

  • Inside <div> tag user can create own html structure.
  • Use input and standard control despite of form and submit tag within main <div> mentioned in the page 1, 
  • Use div and span tag for layout design.
  • Bootstrap style library also provided for layout design, so user can use bootstrap classes for div, span and html controls.

 

Element IDs inside formWidget

  • All html element IDs within the Form Widget should be prefixed with id="formWidget_..." and followed by user defined name. Only alphanumeric and “_” characters are allowed in the ID.

example 1

Widget has a Label control and user wants to use the id as "lblSearch", the ID inside the formWidget control must be prefixed with "formWidget_...", so that the id would be "formWidget_lblSearch".

This id should be unique within the same widget control.

example 2

If a widget has another text control and user wants to use ID as "btnSearch" inside the formWidget, then the control must be prefixed with "formWidget_..." similar to example1.Now the id would be "formWidget_btnSearch" and this id should be unique in the same widget.

 

 

Following code contains highlighted sample element IDs from formWidget as explained in above examples.

 

Event handlers for formWidget Controls

  • Use any valid JavaScript event in html element 
  • Event calling function must exist in the JavaScript section of the same form widget html.

Example 1 -  

If  “lookupData” function is written in JavaScript section and want to call              onclick="lookupData(this, $('#formWidget_txtSearch'),'formWidget_tblData')" event from button, the three parameter used  in this function are: this – object of button, $('#formWidget_txtSearch') – jQuery object of textbox, 'formWidget_tblData' -  string ID of table.

 

2. JavaScript Section

Basic structure of JavaScript should be as following

 Type of Functions from formWidget JavaScript Section.

  • Add two types of functions as following.  
    1. Init Function
      • Init function means initialize function which will work only on page load.
      • Init function as shown in above code highlighted in red box.
      • Init function must be written within $(function () {. . .});
      • Init function must be start with $("formWidget[type^='lookupviewdata']").each(function () { . . . .});
      • In this function type must be formWidget type mentioned in the html section in this example we have mentioned formWidget type as ‘lookupviewdata’ so we are using same in function "…[type^='lookupviewdata']"
      • We can get the formWidget object by Using   $(this), once we get the object we can use it for further operations

 

  1. Event Handler Function -  
    • User can add any valid function which can be called from html controls as shown in above code highlighted in blue box
    • User can write simple or parameterized function 
    • Parameters may be any control id or formWidget id as discussed in page 5. 
    • If formWidget id used as parameter, then user can get all the controls within the formWidget

 

 

Form Widget Example(lookupviewdata.html)

<!--LookupViewData UI Start-->

<formWidget id="formWidget_form" type="lookupviewdata" data-sqlstatement="" data-conn="">

         <div>

             <table>

            <tr>

                <td>

                    <table>

                        <tr>

                            <td><label id="formWidget_lblSearch" style="margin-bottom10px;">Search Data:</label></td>

                            <td><input id="formWidget_txtSearch" class="input-large" type="text" /></td>

                            <td><input id="formWidget_btnSearch" style="margin-bottom10px;" type="button" value="Search" onclick="lookupData(this, $('#formWidget_txtSearch'),'formWidget_tblData')" /></td>

                        </tr>

                    </table>

                </td>

            </tr>

            <tr>

                <td colspan="3">

                    <table class="table " style="width:100%" id="formWidget_tblData"> </table>

                </td>

            </tr>

             </table>

         </div>

</formWidget>

<!--LookupViewData UI End-->

<!--LookupViewData JS Start -->

<script>    

$(function () {

             $("formwidget[type^='lookupviewdata']").each(function () {

            var sFormWidget = $(this).attr('id');

            var slookupViewID = sFormWidget.substring(0, sFormWidget.length - 4);

 

            var lookupViewlbl = '#' + slookupViewID + 'lblSearch';

            var lookupViewtxt = '#' + slookupViewID + 'txtSearch';

            var lookupViewbtn = '#' + slookupViewID + 'btnSearch';

            var lookupViewtbl = slookupViewID + 'tblData';

            $(lookupViewtxt).keypress(function (event) {

                if (event.keyCode == 13) {

                    event.preventDefault();

                         lookupData($(lookupViewbtn), $(lookupViewtxt), lookupViewtbl);

                    return false;

                }

            });

 

             });

         });

 

function lookupData(btnControl, txtSearchControl, sTblID) {

             var tbl = $('#' + sTblID);

        var oFormWidgetControl = $(btnControl).parents("formWidget");

             var sSQL = oFormWidgetControl.attr('data-sqlstatement');

             var oData = $(oFormWidgetControl).data();

             oData.sqlstatement = sSQL.replace("$$VAL$$", $(txtSearchControl).val());

 

             var tblData;

             $.ajax({

            type: "POST",

            url: 'deFormWidgetService.asmx/getData',

            data: '{"sFormWidgetType":"lookupviewdata","oData" : ' + JSON.stringify(oData) + '}',

            contentType: "application/json; charset=utf-8",

            dataType: "json",

            async: false,

            success: function (r) {

                if (r.d) {

                    tblData = r.d;

                }

             });        

             tblData = $.parseJSON(tblData);

             tblData = tblData.oData.tableData

 

             var oCol = []; //GET THE HEADER

             $.each(tblData, function (index, item) {

                 $.each(item, function (key, value) {

                if (oCol.indexOf(key) == -1) {

                    oCol.push(key)

                }

            });

             });

             tbl = $('#' + sTblID);

             tbl.empty();

             var tr = $("<tr>"); //Add THE HEADER

             $.each(oCol, function (i, item) {

            tr.append($("<th>").text(item));

             });

             tbl.append(tr);

 

             $.each(tblData, function (index, item) {

            var row = $("<tr>");

            $.each(item, function (key, value) {

                row.append($("<td>").text(value)); // ADD JSON DATA TO THE ROW

            });

            row.click(function () {

                alert($(this).children("td").html());

            });

                 tbl.append(row);

             });    

}

</script>

<!--LookupViewData JS End-->

 

 

In this above example, there are two functions

  1. Init function for lookupviewdata Form Widget–  This function is written to bind “on enter key pressed event’ on page load to text box.

 

  1. lookupData() function -  This function is written to get the data from the service and bind to the table "formWidget_tblData".

         This functionality interacts with database ,hence requires sql query and database connection string. This sql related data is stored in data-sqlstatement         and data-conn attributes respectively. These data attributes value can be accessed through <formWidget object>.data() in script, as highlighted in the                  above example. 

        Ajax is used to request the service, following are the ajax request attributes.

 

  1. type: type must be "POST" for this service call.
  2. url: url must be 'deFormWidgetService.asmx/getData' this service url is common throughout all the Form Widgets used in this application.
  3. data: this attribute have two mandatory parameters "sFormWidgetType" and "oData", 

in this example "sFormWidgetType" would be "lookupviewdata".

"oData" must be the stringified version of data() result.

  1. contentType: "application/json; charset=utf-8"
  2. dataType: "json"
  3. success: function results stringified JSON. Parse this to json object, access within 

<JSON Object>.oData and use accordingly within the application.

Copy “lookupviewdata.html” file to C:\inetpub\wwwroot\cDevWorkflow\Forms\FormWidgetUITemplates

 

 

 

Server Side DLL

Start Microsoft Visual Studio and select “New Project”. Select “Visual C#” as the language and select “Class Library” as the project type. Also, select .Net Framework 4.5 from the top dropdown. This example will use C# as the development language. This same example can also be written using Visual Basic .Net. Provide Project name as “lookupviewdata”.

Once the Project is created, rename “Class1.cs” to “clsLookupViewData.cs”, it will automatically change the class name too.

Add a reference to cDevWorkflow, navigate to the following directory “C:\inetpub\wwwroot\cDevWorkflow\bin”. Select the files “cDevDecisionEngine.dll” and “deDataAccess.dll”.

Add the “using” statements: cDevWorkflow.cDevDecisoinEngine  and                                              cDevWorkflow.deDataAccess

Let’s start building the class, first implement the interface called: “deIFormWidget”. To implement the interface, we have to implement the “deIFormWidegt.getData” method. Which returns “clsFormWidgetReturn” object.

This example gets the data from database. In order to get the data, it requires connection string and SQL query.  oData  parameter sent from client has the data attributes and they can be accessed through “clsFormWidgetContext” 

Example -This Widget uses two data attributes :“data-conn” and “data-sqlstatement” in html.

clsFormWidgetContext” has getInput method and it requires a attribute: name parameter which returns a string value. To get “data-conn”, getInput("conn"); method can be used which returns a string value. Similarly, for “data-sqlstatement” ,getInput("sqlstatement"); method can be used.

To get data from database, “GetDataTable” Method is used from class clsDataAccess  as shown in the code below.This code requires additional references i.e System.Data and System.Configuration.

Add following data annotations to the class “clsLookupviewdata”, such that cDevWorkflow is able to auto configure the Form Widget.“formWidgetdata” data annotation have 4 default parameters ,they are as following.

formWidgetData

  1. formWidgetName :  This parameter type must be string. Form Widget name should be same as type mentioned in the Form Widget html file, so the Form Widget name would be “lookupviewdata”. This parameter value   is case sensitive.
  2. formWidgetDesc : This parameter type must be string, Form Widget description should be the short description for the Form Widget.
  3. formWidgetCat : This parameter type must be string, category should be one of the category defined in the system for the Form Widget.
  4. formWidgetDisplayName: This parameter type must be string, Form Widget display should be the short name for the Form Widget which will be displayed at Form Widget menu in the form designer.

formWidgetInput – this widget have 2 formWidget inputs

  1. inputName :  This parameter type must be string. inputs name should be same as data attributes mentioned in the Form Widget html file, for example “conn” and “sqlstatement”.
  2. inputDesc : This parameter type must be string, Form Widget description should be the short description for the Form .
  3. required : This parameter type must be Boolean.
  4. dataTypeName: This parameter type must be string, for example “selectConnectString” and “multilineTextbox”.

 

formWidgeEvent- This Form Widget have 2 events,and the annotation is not mandatory as these events are handled on the client side script.

  1. eventName :  This parameter type must be string. For example  “onselectedRow”, “onSearchClicked”.
  2. eventDesc : This parameter type must be string, event description should be the short description for the event.
  3. oParms : This parameter type must be string or string array.

formWidgetStyleAttributes

  1. oAttributes :  This parameter type must be string or string array. Attributes should be valid CSS attributes, for example “background-color”, “min-height”, “min-width”. 

Now the Form Widget is complete, compile the Form Widget to build the DLL.

 

Form Widget Example(lookupviewdata.cs)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using cDevWorkflow.cDevDecisionEngine;

using cDevWorkflow.deDataAccess;

using System.Data;

using System.Configuration;

 

namespace lookupviewdata

{

         [formWidgetData("lookupviewdata""Lookup and display data""Engine""LookupViewData")]

         [formWidgetInput("conn""Database connection"true"selectConnectString")]

         [formWidgetInput("sqlStatement""SQL Query"true"multilineTextBox")]

         [formWidgetEvent("onSelectedRow""Selected row ID from table""rowID")]

         [formWidgetEvent("onSearchClicked""Search button is clicked""searchTerm")]

         [formWidgetStyleAttributes("background-color""min-height""min-width")]

         public class clsLookupViewData : deIFormWidget

         {

             public clsFormWidgetReturn getData(clsFormWidgetContext oContext)

             {

            clsFormWidgetReturn oReturn = new clsFormWidgetReturn();

            string sConnKey = oContext.getInput("conn");

 

            string connectionString = ConfigurationManager.ConnectionStrings[sConnKey].ConnectionString;

 

            string sqlStatement = oContext.getInput("sqlStatement");

 

            clsDataAccess oDA = new clsDataAccess(connectionString, true);

 

            DataTable oDT = oDA.GetDataTable(sqlStatement);

 

            oReturn.oData["tableData"] = oDT;

 

            return (oReturn);

             }

         }

}

 

 

Navigate to the bin/Debug directory where the DLL was compiled, select the DLL: “lookupviewdata.dll”. Right click on the file and select “Copy” from the context menu

Copy the Form Widget dll to the following directory: “C:\inetpub\wwwroot\cDevWorkflow\bin”. 

 

 3. Icon file

First let’s setup an icon for the new Form Widget. Create any icon having 40 x 40 pixels in size and PNG format, name the icon same as the Form Widget name “lookupviewdata”. Copy the file to the following directory “C:\inetpub\wwwroot\cDevWorkflow\images\FormWidgets”.

 

4. Configure Form Widget

Navigate to the FlowWright Configuration Manager and select the “Form Widgets” from the left menu.

 

Select “UtilsAuto Detect” menu item as shown below:

 

 

 

Select the Form Widget(s) from table and select “ManageConfigure” menu item. The Form Widget will be automatically configured within the FlowWright application.

Once the Form Widget is successfully configured, select “UtilsUpdate Master Script” menu item as shown below.

 

 

Navigate to the FlowWright Configuration Manager and select the “Forms”, select the “Form Definitions” option from submenu. Click on “Create” button from menu bar to create a new form.

Once clicked on create button, a pop up window will be displayed

 

Enter Definition Name, Check Open Designer checkbox and Click on the “Create” button.Once form Designer is displayed, search for “lookupviewdata” Form Widget in “All Form Widgets” left menu. Select and drag the “Lookupviewdata” Form Widget on designer section as shown below:

 

Double click on the Form Widget from the Designer or right click and select “Edit” from Context Menu.

On click, the Edit property window will be displayed and all the input and style attribute values can be added as following.

Enter the attributes value as above and click on “Save” button. To see the result of FormWidget ,Click on “Save” icon from the Menu Bar and then click on “Preview” icon as shown below:

 

 

On click on “Preview”, a new window will be displayed and the Form Widget “LookUpViewData” result will be displayed as below: