Search the FirstSpirit Knowledge Base
Hey everyone,
We are currently in the need for an editor rule that displays a validation error if either both or neither of two fields are filled.
(Customer is using 2019-10)
Normally, this would simply require an XOR operator, but it seems that FS doesn't provide/support this?
a) Am I correct in that assumption or am I blind?
b) Why on earth is it, that the WITH-Block must return "FALSE" in order for the DO-Block to correctly apply the property VALID?!
This is extremely counter-/unintuitive.
Currently we have to use two rules to cover our use-case.
Does someone here have a smarter idea on how to do it in one?
Hi Sammy,
a) XOR
There is no explicit XOR because in a boolean context XOR is just equivalent to „not equal“.
So a rule that marks both components as invalid if both are empty or both are filled, looks like this:
<RULE>
<WITH>
<NOT>
<EQUAL>
<PROPERTY name="EMPTY" source="st_text_A"/>
<PROPERTY name="EMPTY" source="st_text_B"/>
</EQUAL>
</NOT>
</WITH>
<DO>
<VALIDATION scope="save">
<PROPERTY name="VALID" source="st_text_A"/>
<MESSAGE lang="*" text="Exactly one of the fields must be filled"/>
</VALIDATION>
<VALIDATION scope="save">
<PROPERTY name="VALID" source="st_text_B"/>
<MESSAGE lang="*" text="Exactly one of the fields must be filled"/>
</VALIDATION>
</DO>
</RULE>
b) Return value
Rules are not (only) used for validation but (more generally) to
1. evaluate some kind of value (in the WITH) and the
2. Kind of "write" those values to other PROPERTIES (in the DO).
Validation is just one use case. And here, it seems absolutely correct to me that you have to put "false" into a property "VALID" to mark something as invalid. Or - as another explanation - you declare what you want, not what you don't want to have a valid field.
Maybe there is also a slight misunderstanding here in general. Rules (and especially VALIDATION) are not an "if - then" concept (at least not when talking about WITH-DO) but "just" some kind of value assignment.
Hope this helps!
Michael
Hi Sammy,
a) XOR
There is no explicit XOR because in a boolean context XOR is just equivalent to „not equal“.
So a rule that marks both components as invalid if both are empty or both are filled, looks like this:
<RULE>
<WITH>
<NOT>
<EQUAL>
<PROPERTY name="EMPTY" source="st_text_A"/>
<PROPERTY name="EMPTY" source="st_text_B"/>
</EQUAL>
</NOT>
</WITH>
<DO>
<VALIDATION scope="save">
<PROPERTY name="VALID" source="st_text_A"/>
<MESSAGE lang="*" text="Exactly one of the fields must be filled"/>
</VALIDATION>
<VALIDATION scope="save">
<PROPERTY name="VALID" source="st_text_B"/>
<MESSAGE lang="*" text="Exactly one of the fields must be filled"/>
</VALIDATION>
</DO>
</RULE>
b) Return value
Rules are not (only) used for validation but (more generally) to
1. evaluate some kind of value (in the WITH) and the
2. Kind of "write" those values to other PROPERTIES (in the DO).
Validation is just one use case. And here, it seems absolutely correct to me that you have to put "false" into a property "VALID" to mark something as invalid. Or - as another explanation - you declare what you want, not what you don't want to have a valid field.
Maybe there is also a slight misunderstanding here in general. Rules (and especially VALIDATION) are not an "if - then" concept (at least not when talking about WITH-DO) but "just" some kind of value assignment.
Hope this helps!
Michael
Hey Michael,
thank you very much for the reply.
You are right, we constantly struggle with the Rules syntax.
I tested your solution and it works like a charm, but I still don't fully understand it.
If you could find the time, could you try to explain what the <WITH> is exactly doing here?
Hi Sammy,
the WITH does just evaluate / "return" an "intermediate" value that is then further "processed" by the "DO" part. "Processing" means "putting that value into other properties".
Maybe the documentation is not that straight forward here but I always explain it as a simple value assignment, regardless if you use it for validation or not.
The above rule can be noted as pseudocode, something like:
text_A.valid = !(text_A.empty == text_B.empty)
text_B.valid = !(text_A.empty == text_B.empty)
\--- DO ---/ \-------- WITH ---------------/
... with the special case / feature here that with the rule syntax you can "write" the value from the WITH to more than one "target" in just one rule. And - by the way - for boolean values you can also use a <NOT> inside the DO (or just for parts of it) - this way you need only one rule if - for example - two fields should behave "oppositely" concering their visibility.
Highlighting fields and forbidding saving/releasing is then a consequence of the applied "validity status" and scope.
Some additional details concerning validation
For "normal" properties (not containing validation!), each property has (or should have...) one defined value at the end - that's the reason why rules without validation should always be "consistent" - meaning without contradictions between rules. A negative example would be two rules that - at the "same time" - evaluate different values for a boolean and write that one to the VISIBLE property of the same input component.
For validation rules, that's a little different. Here, the VALID property of an input component is kind of bound to the "combination" of the rule and the input component, so one input component can have a "combination" of validity states - each of them referring to a rule.
The decision if the input component is then "effectively/finally" considered valid or invalid and - if invalid - in which scope (save, release) with respect of the "behavior" (highlighting, no saving/releasing possible) is then "afterwards" made by the "hightest scoped rule(s) considering it invalid". If there is more than one (e.g. two rules that consider an input component invalid for scope "save"), their messages are even combined.
This allows you to define your validation rules in a more fine granular way to make them easier to implement and also (and that's the more important reason in my opinion) to provide better / more helpful feedback to the editor.
Example:
A text input is used for an URL. In the example, it should be a mandatory field and must start with http:// or https:// and may not contain spaces. If any of those restrictions is not satisfied, the field should be considered invalid in scope "SAVE".
You can of course define just one rule with one regex (or multiple regexes combined with <AND>) covering all restrictions in that one rule and a validation message like "The URL must not be empty, it must not contain spaces and must start with either http:// or https://"
But does not really tell the editor what to change/do.
So from an UX perspective, it might be better to define three independent rules:
These rules may "set" the <PROPERTY name="VALID" source="st_url" /> "differently" inside the VALIDATION part, but in this case that's not considered a "contradiction" as they are just defining "their individual" validity status concerning "their" restriction/requirement. The field itself would only considered valid if all ruled set "their" VALID property to true (or - to be more precise - if none of them sets it to false).
If - for example - you enter an URL like "http:/e-spirit. com", the first rule would consider the field valid (restriction "not empty" is satisfied), but the other two would not. So the URL field would be marked red, you could not save the form and both validation messages would be shown. As soon as you remove the space before "com", that "don't use spaces" message would disappear, but the red highlighting and the "start with http:// or https://" message would still be displayed and you still couldn't save the form. Only when you also add the missing "/" (and maybe also an s) everything is "valid" and you can save.
I hope this is understandable 🙂
Michael
Hello Michael,
this is much more than I could have asked for. Thank you again for your time and patience.
I now realized, that I never fully understood the <Property> Tag but it just made "click" for me.
In my brain, I always thought <Property> would reference one of my template-variables, when in fact, it references individual - well - properties of said variables.
Now that it clicked, I can't even say why I didn't get it before.
Well. We barely use Rules TBH, but as we know: training makes perfect.
So I'll just have to tinker some more with this and I'm sure the rest will click into place as well.
Once more, thank you very much for your time and help.
I hope you'll have a great week.
Cheers and stay healthy!
Hello Sammy,
you are welcome 🙂
I know that the whole "Rules" stuff seems quite complex in the beginning. Especially if you understand it like an "if - then" concept (which will unfortunately even work for some time and simple cases but at some point suddenly stops working and then leads to confusion).
But then - when that magic "click" moment comes - everything suddenly makes sense and gets quite easy 😉
By the way, another general hint: Be very careful when using <IF> (precondition) together with <VALIDATION> because that may lead to some kind of "one way behavior". You can find more information about this here (section "Mandatory fields with complex logic").
Michael
Totally.
I think I just had that "magic moment" as you put it. I just hope it will stick for when I need to create another rule six months from now
The tipp regarding IF and VALIDATION I actually knew/remember from my FS developer training .
BTW: I tried to mark your posts as "helpful" but the function seems to be buggy/broken as they don't seem to stick/save.