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
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.
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