Why is custom js validation function being called twice? How can I pass the Nintex Object with key .isValid into my function explicitly?

  • 12 January 2018
  • 2 replies
  • 6 views

Badge +1

We are running SharePoint 2013 with Nintex Forms: 2.11.0.1

I have an issue where custom validation with the "Custom Validation Function" on a  Single line of Text control fires when I do not want it to. Oftentimes, it also fires more than once.

Fig. 1 Screenshot of control setting

Custom Validation Function

When the function runs

-  it usually runs twice

-  it always runs the first time after I blur out of the input field with the custom validation function

- it sometimes runs after clicking Submit

I've tried running the validation in Form Edit Mode as well as from a published version of the form, but the same outcomes occur regardless.

I've also tried adding () after validateCompanyNameUniqueness (e.g. validateCompanyNameUniqueness() ) which prevents the function from being called more than once, but then the function does not receive the Nintex arguments object with .isValid key. Side question: How do I explicitly pass in the implicit arguments into my validation function from this control setting?

If you want to see the validation code, it's below; however, I am almost positive it is not the custom code that is causing the function to be called at weird times because this happens across different forms and validation functions on our sites.

 

Code

var isNewMode = document.location.pathname.indexOf("/NewForm.aspx") > -1;

// config for Fuse fuzzy match js library
var fuseOptions = {
shouldSort: true,
findAllMatches: true,
threshold: 0.2, // 0.0 -> exact match; 1.0 -> loosest match
location: 0,
distance: 100,
maxPatternLength: 55,
minMatchCharLength: 4,
keys: ["Title"],
includeScore: true
};
var urlQuery = "https://fakeSite.com/sites/vendors/_api/web/lists/GetByTitle('All Vendors')/items?$select=Title&$top=5000";
var allVendorsArray = [];
var previousInput = '';
var confirmKeepInput = false; // Prevents confirm() dialog box from firing more than once if not necessary

NWF$.ajax({
method:"GET",
url: urlQuery,
headers:{"Accept":'application/json;odata=verbose'},
async: false,
success: function(response) { allVendorsArray = response.d.results;},
error: function(error) {alert(error);}
});


var fuse = new Fuse(allVendorsArray, fuseOptions); // Keep here. Needs response from list 


/*
This function checks the vendorNameInput field when a new Vendor is being added for duplicates or similar existing vendors.
*/
function validateCompanyNameUniqueness(args, validator) {
if (isNewMode) {

var vendorLookupControl = NWF$("#" + vendorNameInput);
var vendorControlVal = vendorLookupControl.val().replace(/(^s)|(s$)/g, ""); // removes leading and trailing whitespaces
vendorControlVal = vendorControlVal.replace(/(s){2,}/g, " "); // removes extra whitespace in between words
var newVendorCheck = NWF$("#" + newVendorCheckbox).prop('checked');

// IF the New Vendor checkbox is checked and Vendor Name (Legal) input is not null or empty
if (newVendorCheck && !(vendorControlVal == null || vendorControlVal === '')) {

var fuzzyResults = fuse.search(vendorControlVal);

// IF there are any fuzzy matches
if (fuzzyResults != null && fuzzyResults.length > 0) {

var stringOfVendors = '';
var exactMatchBool = false;

// Build string of matched vendors
for (var index=0; index < fuzzyResults.length; index++) {
var thisTitle = fuzzyResults[index].item.Title;
stringOfVendors += thisTitle + ' ';

// IF there's an exact match
if (thisTitle.toUpperCase() === vendorControlVal.toUpperCase()) {
exactMatchBool = true;
}
}

// Remove trailing newline ( ) tag
stringOfVendors = stringOfVendors.replace(/(^\n)|(\n$)/g, "");

// IF theres an exact match, FAIL validation and return
if (exactMatchBool) {
alert('We've found an exact match for ' + vendorControlVal + ' in our list of Vendor Names. Please uncheck the 'New Vendor / Vendor Not Found' checkbox and select the matching Vendor Name from the dropdown');
failCompanyNameValidation();
previousInput = vendorControlVal;
return;
}
//
if (vendorControlVal !== previousInput) {
confirmKeepInput = false;
}

// IF the user's input has not changed and they have confirmed to keep the input once, pass test
if (vendorControlVal === previousInput && confirmKeepInput) {
passCompanyNameValidation();
} else {
// Confirmation that user wants to keep input
var confirmationBool = confirm('There are Vendor Names that are similar to the value entered in 'Vendor/Company Name (Legal)'. - If you find a Vendor listed below that fits your request click Cancel, uncheck the 'New Vendor / Vendor Not Found' checkbox, and select the Vendor from the 'Vendor (Company)' dropdown. - If you wish to continue using your current value, click OK. Your Entered Value: ' + vendorControlVal + ' ' + 'Similar Vendor Names: ' + stringOfVendors);
if (confirmationBool) {
confirmKeepInput = true;
passCompanyNameValidation();
} else {
passCompanyNameValidation();
confirmKeepInput = false;
} // END if confirm
previousInput = vendorControlVal;
} // END if (vendorControlVal === previousInput && confirmKeepInput) {
} else {
passCompanyNameValidation();
} // END if (fuzzyResults != null && fuzzyResults.length > 0) {
} else {
passCompanyNameValidation();
} // END if (newVendorCheck && !(vendorControlVal == null || vendorControlVal === '')) {
} else {
passCompanyNameValidation();
} // END if (isNewMode)

function passCompanyNameValidation() {
validator.IsValid = true;
// vendorLookupControl.css('border', '');
}

function failCompanyNameValidation() {
validator.IsValid = false;
// vendorLookupControl.css('border', '2px solid red');
}
} // end function validateCompanyNameUniqueness(args, validator) {
// });


2 replies

Userlevel 5
Badge +14

Why is custom js validation function being called twice?

it's because nintex attaches 2 onchange handlers to a control being custom validated.

I'm not sure why it is so, but it sounds to me to be a bug.

I can reproduce it in newest version 2.11.1.10. however this is not the case in older 2.7.0.0

I would say it's worth of reporting it to Nintex Support

I've also tried adding () after validateCompanyNameUniqueness (e.g. validateCompanyNameUniqueness() ) which prevents the function from being called more than once

if you checked developer console, you would see it throws an error.

this is not correct usage.

 How do I explicitly pass in the implicit arguments into my validation function from this control setting?

you can not do that.

custom validation function is invoked dynamically through eval() call with two hardcoded parameters passed in.

‌ validation invoked more times‌ ‌  pass in parameter‌

Badge
found the same bug and done workaround via adding time variable not to let it run twice

Reply