Displaying a Process Timeline Diagram in Nintex Form

Following my previous post on Displaying a Process Flow Diagram in Nintex Form​ that I’ve shared how to include a JavaScript based Process Flow Diagram in Nintex Form. In this post, I am going to show how to include a “Timeline” diagram in Nintex Form using just pure CSS technique. As it uses just CSS, the Timeline will be viewable even in Nintex Mobile App. The outcome of this exercise, you will get to see the below form when form is being filled (i.e. New), and middle of the process timeline to show steps that were completed and yet to be completed.

The “Timeline” is presented by simply a CSS formatted HTML list as shown in the HTML code below, which in my example I have a total of 4 list items (i.e. <li>) to display a 4 process stages timeline.

<ul class="timeline" id="timeline">
  <li class="li" id=""Request Submitted">
    <div class="process">
      <span class="name">Request Submitted</span>
    </div>
    <div class="status">
      <span class="author">Initiator</span>
      <span class="date">06/06/2016</span>
    </div>
  </li>
  <li class="li" id="Manager Approval">
    <div class="process">
      <span class="name">Manager Approval</span>
    </div>
    <div class="status">
      <span class="author">Manager</span>
      <span class="date">06/06/2016</span>
    </div>
  </li>
  <li class="li" id="Finance Approval">
    <div class="process">
      <span class="name">Finance Approval</span>
    </div>
    <div class="status">
      <span class="author">Finance Manager</span>
      <span class="date">06/06/2016</span>
    </div>
  </li>
  <li class="li" id="Request Processed">
    <div class="process">
      <span class="name">Procurement</span>
    </div>
    <div class="status">
      <span class="author">Proc Admin</span>
      <span class="date">TBD</span>
    </div>
  </li>
 </ul>

For the exercise, I have created a Sharepoint Custom List with just two columns (i.e. Title as Single line of text, and Timeline as Multiple lines of text). Timeline column is used to store the Timeline HTML source shown in the figure above. At each process stage, the Workflow will update the Timeline data to indicate if a process stage is “Complete“, the “author” value is updated with the person who performed/completed the process stage, and the “date” of the process stage being completed.

Create a Nintex Form to be used as the Sharepoint List form of the custom list. Arrange the defaulted two controls (i.e. Title and Timeline) so that it looks similar to the diagram below. drag and drop a “Multi Line Textbox” to the red dotted box (i.e. on top of the “Timeline” list column control) as shown in the diagram below. The red dotted box area should have two form controls (i.e. Timeline and Multi Line Textbox), one on top of the other.

Configure the “Multi Lines Textbox” by copying the Timeline HTML code shown in the previous diagram to the Default value of the control, and configure the Appearance – Visible with value as shown in diagram below. The formula of the Appearance – Visible property is to show the “Multi Line Textbox” control when the List Column “Timeline” is empty or null.

Open the List Column “Timeline” control to add the Appearance – Visible property as shown in diagram below. The formula used in Appearance – Visible property is to show the “Timeline” list column control if it’s not empty or null.

We will need to include our custom CSS to format the Timeline to the format we want. Here is the CSS code I used in my example

.timeline {
  list-style-type: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.li {
  transition: all 100ms ease-in;
}
.process {
  margin-bottom: 5px;
  padding: 10px 10px;
  display: flex;
  align-items: center;
  font-size: 12px;
  font-weight: 100;
}
.status {
  padding: 15px 10px;
  display: flex;
  align-items: center;
  flex-direction: column;
  border-top: 2px solid #CFD2D5;
  position: relative;
  transition: all 100ms ease-in;
}
.status .author {
  font-weight: 200;
}
.status .date {
  font-weight: 200;
  font-size: 12px;
}
.status:before {
  content: "";
  width: 25px;
  height: 25px;
  background-color: white;
  border-radius: 25px;
  border: 1px solid #8A8A8A;
  position: absolute;
  top: -15px;;
  left: 42%;
  transition: all 100ms ease-in;
}
.li.complete .status {
  border-top: 2px solid #22BB22;
}
.li.complete .status:before {
  background-color: #22BB22;
  border: none;
  transition: all 100ms ease-in;
}
.li.complete .status .author {
  color: #22BB22;
}
.li.complete .status .date {
 color: #22BB22;
}

I have appended the code directly to the “Custom CSS” settings of the form as shown below

Now that we are done with the form design. In order to show the timeline with completion/timeline status, we will need to include actions in our workflow to update timeline data reflecting the status of the process stage(s)/timeline. I have attached my sample workflow for reference purposes, which carries the following summarised key actions.

1. Query the “Multi Line of Textbox” control value from Nintex Form.

As the “Timeline” list column control of type multiple lines of text does not allow us to set default value in form, we have introduced the “Multi Line of Textbox” form control without it “Connected” to the “Timeline” list column. We then perform this action (i.e. Query XML) to query the Nintex Form data, so we could save it to the Timeline list column in the workflow. Diagram below shows the configuration of the Query XML action, to which it queries the “/FormVariable/Timeline” and store the result to the workflow variable – “TimelineXML“.

2. State Machine branch – “Decode TimelineXML”

The “Decode TimelineXML” state machine branch performs few actions to decode the TimelineXML data that was encoded, and saved the decoded HTML code back to TimelineXML variable. The outcoe of the actions are being logged in attached workflow, diagram below shows the my workflow performed actions to extract the Timeline data from the NFFormData, and the extracted Timeline data in encoded format, and the outcome of the “Encode TimelineXML” steps.

3. State machine branch – “Extract Timeline”

Performs actions to extract the four process stages list item represented by <li> tag in the html code. The 4 list items will be saved to “ProcessState1“, “ProcessState2“, “ProcessState3“, and “ProcessState4” workflow variables respectively. With the extracted states data save in the workflow variables, we can update the data at different stages of the workflow. This is done by four “Query XML” actions, each to extract the <li> tag of each process timeline. the configuration of the Query XML is shown below.

4. The remaining “State 1” to “State 4” branches.

The remaining 4 branches in my example shows how the data of the “ProcessState1”, “ProcessState2, “ProcessState3”, and “ProcessState4” could be updated to reflect the status of the state. Once a “State” is updated, the reconstruction of the “TimelineXML” could be done by the “Update XML” action to reconstruct the content by replacing it with the updated workflow variables (i.e. ProcessState1, ProcessState2, ProcessState3, and ProcessState4). The “Update XML” configuration is shown below.

We concluded these branches’ with the “Set Field in Current Item” action to set/update the “Timeline” list column with the newly constructed “TimelineXML” value. As “Timeline” list column is now updated with data highlighting the status of the timeline, the Form will now show it’s content instead of the initialized “Timeline” form control data. (i.e. defaulted timeline data).

Displaying a Process Flow Diagram in Nintex Form

As named, if you would like to include a high level “process flow diagram” on a form, here is my sharing on direction and quick start to do that. The concept and requirement I got here is a high level process state diagram of the document/process flow, showing Past, Current, and Future state of the business process on the form. The diagram below shows the sample outcomes of the form on Office 365 with a Process Flow/State Diagram in the top banner of the form.

Process Flow - 1.png
Process Flow - 2.png

The solution is accomplished by flowchart.js Javascript Library which is based on Raphaël—JavaScript Library​. It draws the “Process Flow Diagram” on the fly when the Form is open for viewing or editing. The data of the diagram is saved as “Multiple lines of text” column of the Sharepoint list, as such it could be updated by Nintex workflow action(s) to change the state of the flowchart when needed. I have named my “Multiple lines of text” in my example as “WorkflowStatus“, which is linked to Nintex Form’s “Multi line textbox” as shown in the below diagram.

Untitled picture.png

The two Javascript libraries (http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js ​, http://flowchart.js.org/flowchart-latest.js ) to be included in the Form settings as shown here.

Untitled picture.png

Include the following “Custom Javascript” to the “Form Settings“. Line 3 to 10 in the script defines the diagram to be displayed. Line 37 to line 73 are attributes of the diagram allowing you to define the attributes such as color code, line length, etc. of the diagram. (i.e. you may refer to flowchart.js​ on all the available settings).





NWF$(document).ready(function(){  
    var code    = 'st=>start: Start\n'
            + 'e=>end\n'
            + 'op1=>operation: Manager Approval\n'
            + 'op2=>operation: Finance Approval\n'
            + 'op3=>operation: Procurement\n'
            + 'st(right)->op1(right)->op2(right)->op3(right)->e\n'
         ;

  if (NWF$('#'+workflowstatus).val()==''){
  NWF$('#'+workflowstatus).val(code);
  }

  NWF$("div.nf-filler-control[data-controlname^='WorkflowStatus']").add("div.nf-filler-control[data-controlname^='workflowstatus']").each(function () {    
       var codeUI = NWF$(this).find("div.nf-filler-control-inner");        
       var codeO365View = NWF$(codeUI).find("div");        
       var codeO365Edit = NWF$(codeUI).find("textarea");    
       var codeOnPrem = NWF$(codeUI).find("input[type=text]");    
       var codeContent;     

    if (codeOnPrem.length != 0) {   
        codeContent = codeOnPrem.val();    
       } else if (typeof codeO365Edit.val()== 'undefined') {
    codeContent = codeO365View.html().replace(/<br>/g,'').replace(/&gt;/g,'>');
    } else {
    codeContent = codeO365Edit.val()
    }   

       //codeContent = ((typeof codeO365Edit.val()== 'undefined')? codeO365View.html().replace(/<br>/g,'').replace(/&gt;/g,'>'): codeO365Edit.val());   
    codeUI.css('visibility','hidden');
    codeUI.after('<div id="canvas"></div>');
    codeContent = ((codeContent == '') ? code : codeContent);
       var chart = flowchart.parse(codeContent);
       chart.drawSVG('canvas', {
                      // 'x': 30,
                      // 'y': 50,
                      'line-width': 3,
                      'line-length': 25,
                      'text-margin': 5,
                      'font-size': 14,
                      'font': 'normal',
                      'font-family': 'Helvetica',
                      'font-weight': 'normal',
                      'font-color': 'black',
                      'line-color': 'black',
                      'element-color': 'black',
                      'fill': 'white',
                      'yes-text': 'yes',
                      'no-text': 'no',
                      'arrow-end': 'block',
                      'scale': 1,
                      'symbols': {
                        'start': {
                          'font-color': 'red',
                          'element-color': 'green',
                          'fill': 'yellow'
                        },
                        'end':{
                          'class': 'end-element'
                        }
                      },

                      'flowstate' : {
                        'past' : { 'fill' : '#CCCCCC', 'font-size' : 12},
                        'current' : {'fill' : 'yellow', 'font-color' : 'red', 'font-weight' : 'bold'},
                        'future' : { 'fill' : '#FFFF99'},
                        'request' : { 'fill' : 'blue'},
                        'invalid': {'fill' : '#444444'},
                        'approved' : { 'fill' : '#58C4A3', 'font-size' : 12, 'yes-text' : 'yes', 'no-text' : 'no' },
                        'rejected' : { 'fill' : '#C45879', 'font-size' : 12, 'yes-text' : 'n/a', 'no-text' : 'REJECTED' }
                      }
                    });
  });
});

As my actual workflow is performing a series of complex workflow actions, I do not expect the business users to visit for details such as which state it is executing, I include the following sample workflow actions to update the “Multiple lines of text” item property which will reflect the “Process Flow Diagram” on the Form for business users.

Untitled picture.png

I am leaving the update of the “Multiple lines of text” open as I believe it could be or should be done in a better approach than my sample here….

Nintex Form – Runtime function as parameter to Javascript call for setting form controls’ value

The intention of this write up is to demonstrate how to pass runtime function – (in Nintex Form calculated value control) – to JavaScript for setting controls’ value. It also features the following techniques for extending NINTEX Form capabilities:

  • Capturing of “Change” event from multiple editable controls (i.e. single line of text control) to trigger JavaScript function call
  • Using JavaScript to set form controls’ value (i.e. based on data captured during the form filling)
  • Using userProfileLookup runtime function to retrieve Sharepoint User Profile attributes (i.e. Distinguished Name in this example)
  • Hide a calculated value control in form with CSS Style
  • Regular Expression to extract different occurrences of OU in Distinguished Name

The outcome of this exercise is shown in the diagram below, where changes made to either Title or Requester field in the form causes the calculated value (i.e. circled in RED in the diagram) to call a custom defined JavaScript function (i.e. setControlValue function in this case) and pass the form’s runtime function (i.e. userProfileLookup – returns Requester’s Distinguished Name) value as parameter of the JavaScript’s  function, setControlValue function is to set values of both OU1 and OU2 “single line of text” control as shown in the following diagram.

Here are the steps to reproduce the above described outcome:

1. Create a custom list (i.e. “Set Form Control Value” custom list in my example) with list columns as shown in following diagram

2. Using Nintex Form to customize the custom list’s form, Nintex Form designer drew the form as shown in the diagram below automatically based on the defined custom list’s columns.

3. As we are going to use JavaScript to set value for controls OU1 and OU2, with data from Title control and form runtime function, we will need to set the “Client ID javaScript Variable Name” for reference by JavaScript at the later stage. The following diagram shows how the Client ID JavaScript Variable Name is being set for “Title” control as “title” (i.e. case sensitive). We will need to repeat the same for the other two controls named – OU1 and OU2 with Client ID JavaScript Variable Name as “ou1” and “ou2” respectively.

4. Add a “Calculated Value” control to the bottom of the form as shown below

5. Edit the formula of the “Calculated Value” control – RequesterDN in my example with formula as shown in the diagram below. The runtime formula of userProfileLookup to lookup “SPS-DistinguishedName” from the Sharepoint’s User Profile of the “Requester“.

6. Define a custom JavaScript in the Form’s setting for setting values of OU1 and OU2 controls, with below JavaScript

function setControlValue(value){try {  var ou1array = value.match(/^(?:.*?OU=){0}[^,]*[,](.*?)(?=,|$)/i);  var ou2array = value.match(/^(?:.*?OU=){1}[^,]*[,](.*?)(?=,|$)/i);  NWF$('#'+ou1).val(ou1array[1]);  NWF$('#'+ou2).val(ou2array[1]);}catch(err){};return value;}

The custom JavaScript defined in the Form’s Setting window is show in the following diagram

7. As we have now defined the JavaScript function (i.e. setControlValue(value)), we’re going to make changes to the calculated value control (i.e. added in Step 4 above) to call the setControlValue and pass the userProfileLookup function as parameter to the JavaScript call. Here is how the modified Calculated Value control’s formula looks like. After that is done, you may proceed to publish the form for testing.

8. For the form testing purpose, I have to created different users with /or under different OU(s) as shown in my example in below diagram. I have created two users – “Sales Person 1” and “Sales Person 2” for testing purpose with respective Distinguished Name as below

CN=Sales Person 1,OU=Sales Office 1,OU=North Region,OU=Sales Organization,DC=crestan,DC=local

CN=Sales Person 2,OU=Sales Office 2,OU=North Region,OU=Sales Organization,DC=crestan,DC=local

9. With the form published, you may test the form by entering “Requester” field with the created user (i.e. Sales Person 1 in my example), the results are shown in following diagram with OU1 and OU2 set to the OU1 and OU2 of the Requester‘s Distinguished Name

10. Try making changes to both the Title and/or Requester field with different value, which will trigger the Calculated Value control to call the JavaScript function for resetting OU1 and OU2 value.

11. As we are using technique of Calculated Value to call get the Distinguished Name based on the Requester field value, and passed the runtime function lookup value to JavaScript function call, we would like to hide the Calculated Value control as it is not needed to the end users. One easy way of doing it is of course using the default control setting’s visible attribute to “No“, but you will then realized the control will also be totally hidden causing the desired functionality to fail. One work around is to use CSS to set the visibility to “hidden” but the control is actually available for the said purpose. In my example I have defined a CSS class as shown “.nf-form-footer

with that, we can then set the Calculated Value control’s CSS Class to defined CSS Class (i.e. .nf-form-footer in my example) as shown below. If you noticed, I have added the Title control reference in front of the formula, which causes the Calculated Value being triggered when changes made to the Title field, and causes the calling of JavaScript to set controls’ value again.

Once done, publish the form and you will get the below sample outcome when tested. (Noticed that the Calculated Value control is now hidden from users)

Embedding Signature Pad in Nintex Form

I was asked by a partner recently on the availability of Signature pad in Nintex Form, and I am sharing how I did it using the jSignature library from jSignature. This is to demonstrate how to embed a Signature Pad in Nintex Form for Signature capture, store, and display using the said jSignature.min.js javascript library. The data of the signature is stored in a text field for redisplaying when the form is opened. What you will need is just the jSignature.min.js file to be uploaded to your site for later inclusion into your “Custom JavaScript Includes” of the Form, also don’t forget you will need the jQuery liabrary to be included as well if it is not already done for the site or site collection level.

The result of the steps here is shown in below screen captured – Nintex Form with Signature Pad for signature drawing capture,

For the purpose, i have created a simple Custom List on my Office 365 Sharepoint site environment, with only two columns – Title, and Signature (i.e. both are single line of text) to store the title of the signature, and the signature data respectively, here is how the custom list setting looks like

With the custom list created, I have then customized the form with Nintex Form as captured below. My form consists of only three fields (i.e. data controls) – one for Title, one Rich Text Control for the Signature Pad, and Single Line of Textbox to store the Signature.

Include the “Custom Javascript” and “Custom Javascript Includes” as shown below, i have downloaded and saved the “jSignature.min.js” library to the SiteAssets folder of my Sharepoint site.

The JavaScript is to initiate the Signature Pad for signature drawing, or to re-draw the Signature from the captured Signature data if the form is opened for viewing or editing,

NWF$(document).ready(function() {  
var savedSig = NWF$(‘#’+sig).val();  
var sigdata = $(‘#signature’).jSignature();  
if (savedSig != “”) {    
var dataurl=’data:’+ savedSig;    
sigdata.jSignature(‘importData’,dataurl);  
}
})

The “Rich Text” control of the Nintex Form consists of only one line of HTML code “<div id=”signature”></div>“, here is how it looks like in the Control’s Setting

The “Single Line of Text Box” form control is configured as below, where I have inserted the “Client ID JavaScript variable name” as “sig” for the JavaScript references.

The form’s “Save” button is being configured as below to include the the following JavaScript (i.e. set the “Signature” control value with the Signature data when the form is being saved),

NWF$(‘#’+sig).val($(‘#signature’).jSignature(‘getData’, ‘base30’));

under the Advanced – Client click setting

That’s all you need to embed a Signature Pad in Nintex Form. Publish the form, and you should get a Signature Pad where you can draw signature, save the Signature in the Custom list, and displaying the signature when the form is opened for viewing or editing.