Solved

Why a custom validation function runs twice?

  • 12 May 2021
  • 6 replies
  • 315 views

Badge +6

I have added a custom validation function to a field (Choice)  on a task form.

The js function is within a referenced file.

The signature is 

validateRuleClass = function(source, arguments) { ... }

The code in that function is working fine, but I noticed that the function is called twice.

How to avoid the second call?

What can cause such issue?

This is about SharePoint 2013 On-Premises

icon

Best answer by MegaJerk 13 July 2021, 17:44

View original

6 replies

Userlevel 5
Badge +14

It could be any number of things. Some controls have update phases that aren't straight forward, especially when changed, so it could just be the control going to some in-between state before finally updating to a value that had to be grabbed through some non synchronous method. 

Also validations rules can be evaluated both at the time of *certain* control events on form, but also always when you submit a form. 


 


Is the second evaluation causing an issue? 

Badge +6

It is annoying to the people.

Userlevel 5
Badge +14

Then I can only assume it's because your validation function is doing something that is noticeable to the people, and to change your code so that if it has already reached the state that it should be in, not to take whatever action it takes that your users are seeing. 

if you want me to look at your code, post it, otherwise please mark this thread as solved. 

Badge +6

The validation function is just checking four control values to enforce an approval rule.


 


validateBL = function(source, arguments) {
try {
var ausland = NWF$('#'+ctlAuslandsreise).prop('checked');
var hotel = NWF$('#'+ctlHotelCategory).val();
var flightClass = NWF$('#'+ctlFlightClass).val();
var bl = NWF$('#'+ctlBL).val();

var retval = true;

if(bl === undefined || bl === null || bl === "") {
if(ausland === true || flightClass.indexOf('Premium') > -1 || hotel === "> 170 €") {
alert("Bei Auslandsreisen, Premiumflügen oder Hotelkosten über 170 € muss ein Bereichsleiter oder der Geschäftsführer angegeben werden.");
retval = false;
}
}

arguments.IsValid = retval;
}
catch(e) {
console.log("Bei der Prüfung der Regel für den Bereichsleiter ist leider ein Fehler aufgetreten. Fehler: "+JSON.stringify(e));
arguments.IsValid = false;
}
}

 


The validation is working fine but the message comes twice, if the rule is fullfilled.

Userlevel 5
Badge +14

It seems like this would be solved by simply using the built in Rule System instead of rolling your own alert warning. 

Rules can be evaluated whenever a referenced Control is changed / updated, as well as when the Form is submitted. Because you've only given me the custom function you've written but not the actual body or location (internal to control settings or external in the general rules) I'm still unable to really see what might be causing the double eval.


 


Regardless, here are a few approaches which could solve your problem.


Here is the test form that I made with the Control Names added to the right of each control: 



 


In this example I've put a regular Validation Rule on the control_Manager control: 



 


The Rule is just a condensed version of what you had in your custom function: 



 


Code:


(isNullOrEmpty({Self}) && (control_Ausland && control_HotelCategory === "> 170 €" && control_FlightClass === "Premium"))

 


 


What it looks like: 



 


If you really really want the pop-up, then I think this janky work around should probably work. Because Validation Rules provide you with the ID of the control they are evaluating, we can save some data to that control to reference whenever we're evaluating the rule. The value we'll set will indicate to use what the last validation results were, so we can use that as a means to determine whether or not to show our alert message. 


 


The Custom Function: 


var validationFunction = function(targetControl, ausland, hotel, flightClass, manager) {

var isInvalid = false;

if (!manager) {
if (ausland && hotel === "> 170 €" && flightClass === "Premium") {
isInvalid = true;
if (!targetControl.data("isInvalid")) {
alert("Bei Auslandsreisen, Premiumflügen oder Hotelkosten über 170 € muss ein Bereichsleiter oder der Geschäftsführer angegeben werden.");
}
}
}

targetControl.data("isInvalid", isInvalid);

return isInvalid;
}

 


The Rule Formula: 


(function(rowIndex, ausland, hotel, flightClass, manager){
var targetControl = NWF$("#" + rowIndex);
return validationFunction(targetControl, ausland, hotel, flightClass, manager);
}(rowIndex, control_Ausland, control_HotelCategory, control_FlightClass, control_Manager));

 


Warning! Remember that the very bottom code is actually REFERENCED using the Named Controls tab!: 



 


 


Doing this will result in the Warning being shown ONLY ONCE if the control is invalid several times in a row


 


First time hitting Save



 


 


Second Time (it doesn't show alert):



 


 


I hope this helps to solve your problem. Let me know if you have any further questions. 

Badge +6

MegaJerk,


 


thank you so much for your detailed explanations. This sounds completly plausible and i will try it this way.

Reply