Question

Can't Return Validation Message

Hello, I am attempting to create a validation rule that goes through a number of esq objects with a loop and prevents saving based on their values. But I can't figure out how I can properly trigger it. Either the return and if statement fire at the same time as the loop and nothing happens, or I try to put the return in the loop and the page hangs.

Here is my current attempt.

 

 periodicalValidation: function() {
				var invalidMessage = "";
 
				var message = "";
				var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
				 rootSchemaName: "UsrPeriodicals"
				});
 
				esq.addColumn("UsrName", "Name");
				esq.addColumn("UsrFrequency", "Frequency");
				esq.addColumn("UsrActive", "IsActive");
				var invalidMessage = "";
				var counter = 0;
				esq.getEntityCollection(function (result) {
			 	if (!result.success) {
 
					this.showInformationDialog("Data query error");
						return;
			 	}
 				result.collection.each(function (item) {
 
 				 	if(item.get("IsActive") == true && item.get("Frequency").displayValue ==     "Daily") {
 
 				 		counter +=1;
 				 	};
				 });
 
				 if(counter === 5) {
				 invalidMessage = this.get("Resources.Strings.ActiveValidate");
			}
			return {
 
                   invalidMessage: invalidMessage
               };
 
			}, this);
			}

 

Like 0

Like

5 comments

Dear Nick,

The problem is that the validation method is synchronous, but ESQ is not. 

You can find more information about synchronous and asynchronous methods here https://eloquentjavascript.net/11_async.html since that is not a part of bpm'online functionality, but part of JavaScript language.

ESQ method running and completing asynchronously, so periodicalValidation method finishes his execution before ESQ callback is finished. Since that "return" from ESQ callback doesn't do anything.

The common way to avoid this is a little bit tricky and need some experience in development. Here the main ideas of how you can implement this functionality.

First of all, we are not going to rewrite the validation method, it will not work here. You will need to rewrite "save" method, so if your check will go well we will let card save, if not, we will not let the card save and throw the message to the user.

So here the step by step logic:

1. Create attribute for storing information of completing the ESQ like:

"IsValidationEsqFinished": {
   dataValueType: this.Terrasoft.DataValueType.BOOLEAN,
   type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
   "value": false
},

2. Create attribute for storing the result of validation like:

"IsValidationSucceed": {
   dataValueType: this.Terrasoft.DataValueType.BOOLEAN,
   type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
   "value": false
},

3. Rewrite "save" method 

save: function() {
    // ... logic here
    // ... this.callParent(arguments); somewhere in logic     
 },

Ang here all algorithm need to be written. Algorithm is:

3.1. Save the scope to the variable:

var cardScope = this;

3.2. Check IsValidationEsqFinished, if it false, run your ESQ code.

3.3. In callback of ESQ,

 - Set the IsValidationEsqFinished to true through the saved scope variable:

cardScope.set("IsValidationEsqFinished", true);

 - Set the IsValidationSucceed according to ESQ results and your validation logic to the true or false.

 - Run save method again in order to go through second way (IsValidationEsqFinished === true way.) through the saved scope variable:

cardScope.save();

3.4. If IsValidationEsqFinished is true (this is an alternative way of 3.2. written not in the ESQ callback) we just need to check  IsValidationSucceed and

3.5. If IsValidationSucceed is true run the this.callParent(arguments); which will save the card.

3.6. IsValidationSucceed is false:

 - Set the IsValidationEsqFinished to false;

 - Show the message to the user with information about the bad validation result.

Here the idea of the algorithm, the final realization is up to you. Hope it will help.

Anastasia Botezat,

Hello, I am trying to run a bare bones version of this code to make sure save functionality still works. If I override the save method then I don't see how any changes will actually be saved. Wouldn't I need the code for actually saving? 

 

Nick,



Actual saving will be triggered via the "parent code call" (this.callParent(arguments);) try this:

 

save: function() {
    this.callParent(arguments);
 },





it will work well and will save the changes and close the card.

If you for some reason will not run the this.callParent(arguments);, changes will not be applied and card will not be closed.

Anastasia Botezat,

Sorry, but I have further issues. 

This code

cardScope.set("IsValidationEsqFinished", true);

Does not set the boolean. Because that just refers to the function and not the value.

I've tried IsValidationEsqFinished.value", true, IsValidationEsqFinished", value, true, and IsValidationEsqFinished", "value", true but none of these have worked, what is the proper way to do this?

 

Nick,

cardScope.set("IsValidationEsqFinished", true); is setting the value to the virtual attribute, but not a function. Therrefore, the attribute needs to be added to the attributes section of page schema. Also, to work with attributes and set or get its values you need to use corresponding set and get methods.

Please see the screenshot for more details:

Moreover, we advise you to look through our SDK where you will find common development solutions and development practice in bpm'online.

https://academy.bpmonline.com/sites/default/files/documents/docs_en/tec…

Regards,

Anastasia

Show all comments