cancel
Showing results for 
Search instead for 
Did you mean: 

Creating Real Time Validation on Nintex Forms

scheevel
Nintex Newbie
12 5 2,845


( developed for SP2013 on-prem, Nintex forms 2.10 )


This code was inspired by nmarples whose amazing blog post can be found here. He lifts the curtain on the Nintex rules engine and shows the power of combining Javascript with rules, providing clues to this realtime validation concept.

You can implement this solution right away on any form control without any additional configuration, cut and paste as shown below using these 4 simple steps;

1) make sure each form field control is named and the label is associated with the control:

2) paste this CSS in the form's Custom CSS setting:

.lp-border-red {
  background-color : rgba( 255,0,0,.2 );
}
.lp-border-yell {
  background-color : rgba(255,255,0,0.3);
}
.lp-border-grn {
  background-color:rgba(0,255,0,0.3);
}

3) paste this Javascript in the form's Custom JavaScript setting:

lpForm = {

 Validate: function( formControlCall, sourceContext, required, isValid ) {
  // Obtain the internal element input name.
  var formControlID = formControlCall.split( "'" )[1] || "";
  var internalElement = sourceContext.find( "[name^='ctl'][formcontrolid='" + formControlID + "']" );
  // During initial load, people control is a placeholder, no internalElement exists yet, so bail, validation will succeed later
  if ( internalElement.length == 0 ) return;
  var internalElement_name = internalElement.attr( 'name' );
  // Scrub the name.

  var intext = internalElement_name;
  var outtext = intext.split( '$' ).join( '_' );
  // Obtain the label associated for-name of internal element.
  var labelBorder = NWF$( "[for^='" + outtext + "']" )
    .closest( '.nf-filler-control-border' )
    .parent();
  // Required missing.
  if( required && isValid ) labelBorder
    .addClass( 'lp-border-red' ).removeClass( 'lp-border-yell' ).removeClass( 'lp-border-grn' );
  // Optional missing.
  if( !required && isValid ) labelBorder
    .addClass( 'lp-border-yell' ).removeClass( 'lp-border-red' ).removeClass( 'lp-border-grn' );
  // Not missing.
  if( !isValid ) labelBorder
    .addClass( 'lp-border-grn' ).removeClass( 'lp-border-yell' ).removeClass( 'lp-border-red' );
  return isValid;
 },
};

4) paste this expression into a new rule for each form field you wish to validate

( function( formControlCall, isValid ) { lpForm.Validate( formControlCall, sourceContext, true, isValid ) }( "{ControlSmiley Frustratedelf}", {ControlSmiley Frustratedelf} == '' ) );

optional : inside the expression, change true to false to change the field from required to optional

note : in the Condition window {ControlSmiley Frustratedelf} will format itself to appear as {Self} once saved 

Done - Enjoy!


TL;DR Explanation

The above code is a prototype created in an afternoon. There are probably some edge cases that may require additional coding, but this appears to be suitable for all basic form controls.

The 3 important concepts from nmarples that he shares in his blog post are:

  • The Rule's Condition expression is evaluated as Javascript. ( This means you can point to any Javascript function in the Condition window and it will be executed )
  • You can pass to your function, both, a reference to the current control as a string parameter
    "{ControlSmiley Frustratedelf}"
    and pass the resulting expression as a boolean parameter
    {ControlSmiley Frustratedelf} == ''
    Nintex Runtime Functions this expression is the same as isNullOrEmpty({ControlSmiley Frustratedelf})
  • During the OnChange event the function and parameters be executed in an IIFE ( what's an IIFE? Google it, it's useful… )

CSS

3 classes are used to set the associated control back-grounds to red, yellow or green.

Form JavaScript

lpForm : creates a unique namespace where I can safely use any name for my function.

Validate : takes 4 parameters.

formControlCall : a reference to the currently active control
sourceContext : a reference to the context of the DOM
required : true or false ( whether this form field is required or optional )
isValid : true or false ( the result of the provided validation expression - already evaluated )

The process of the function

  1. Navigate the DOM to locate the current control's internal element name, it usually looks like: 
    ctl00$PlaceHolderMain$formFiller$FormView$ctl26$ctl16$ac5d43fc_51e7_4d06_b3e8_150731c4bac9
  2. Scrub this name to replace "$" with underscores.
  3. Use the name to locate the associated label control - the label uses an attribute named for.
  4. Locate the parent-border control of the labels.
  5. Use .addClass.removeClass to set the label parent-borders to the appropriate CSS class ( background-color )

IIFE

The immediately-invoked function expression gathers the following run-time provided parameters:

a reference to the current control : "{ControlSmiley Frustratedelf}"

and a the validation expression : {ControlSmiley Frustratedelf} == ''

So the IIFE evaluates these two parameters and passes results into the interior function, were all four parameters get passed to the base Validation function.  Then the base function Validation ultimately returns back the isValid boolean, which could be consumed by the Rule too.

5 Comments
Automation Master
Automation Master

This is awesome! Thank you so much for sharing and great work! 

Automation Master
Automation Master

This is wonderful. Will definitely be using this. 

Automation Master
Automation Master

Great to see how all the ideas and knowledge sharing spreads across the community

Automation Master
Automation Master

That's pretty cool!

scheevel
Nintex Newbie

Minor refactor ...apparently, in edit mode, a populated people control only has an empty placeholder.  So when the first wave of validation hits this control fails to validate and pops an error in an alert-box.  ( the control must be waiting to finish a call to display person deets ).  But once populated, validation is triggers again and all if well.  So I needed to add an escape hatch, return from function when DOM query length is 0.